首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如果不显式提交事务,Hibernate如何使用多个session.update()来控制事务?

如果不显式提交事务,Hibernate如何使用多个session.update()来控制事务?
EN

Stack Overflow用户
提问于 2020-06-18 01:57:33
回答 1查看 284关注 0票数 0

我继承了一个系统,它使用Spring MVC和Hibernate存储到DB2数据库中。最近它开始出现DB2报告的死锁问题,所以我一直在调试它。我不是Spring或Hibernate专家,但我对这两种语言都了解一些。

代码的结构如下:

代码语言:javascript
运行
复制
controller -> service -> one or more DAO classes that performs the updates

在出现问题的情况下,控制器调用带有@Transactional@Override注释的服务方法。该服务转到用@Repository注释的DAO类,并调用用@Transactional@Override注释的多个方法。这就是代码的结构。

一个控制器调用一个服务方法。服务方法调用多个DAO方法。大多数DAO方法都被标记为@Transactional@Override。有几个在@Transactional中有REQUIRES_NEW。而且,在每个DAO方法中,SessionFactory.getCurrentSession()都会获取Session

第一个问题:使用这种方法,事务从哪里开始,最终提交在哪里?那么回滚呢?所有这些都没有显式编码。

当其中一个方法更新了一条记录,然后随后的方法删除了该记录时,就会出现死锁。如果您想知道为什么有人想要这样做,那么更新将添加想要删除记录中信息的人的用户id,以便存储的进程可以将其保存到另一个表中。然后,第二个方法调用删除该记录。

最初的程序员试图将REQUIRES_NEW添加到@Transactional中,认为一个新的事务将确保更新会发生。但是死锁仍然以不规则的时间间隔发生。

我尝试将更新更改为本机SQL调用,但Hibernate不允许我启动另一个事务,因为一个事务已经打开。

这里有没有人有什么建议?

EN

回答 1

Stack Overflow用户

发布于 2020-06-18 02:52:17

当一个方法(调用链中的哪个类或方法本身首先用@Transactional注释)从外部调用(它必须从类的外部调用,因为注释“创建”了一个代理)时,事务就开始了。链中具有默认传播级别的任何其他带注释的类/方法都将加入该事务。当调用带有事务标记为REQUIRES_NEW的方法时,父事务将被挂起(如果存在),并且新事务开始。请注意,如果您从同一个类中的其他方法调用带注释的方法,那么它将不会通过代理,因此它与您删除注释相同。提交发生在启动事务返回的方法之后。与回滚相同,抛出异常后会回滚。死锁可能来自不同的地方,即使你有代码也很难找出来。例如,它可能来自update和存储过程,试图锁定某些行,以及发生循环等待等。

我有一个天真的图像,背景中发生了什么。有两个类ui和服务。该服务被注释为@Transactional。Spring创建代理,所有来自外部的调用都要经过它。在调用真正的方法之前,它会启动事务,然后提交。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62435453

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档