首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在遗留软件中混合编程事务和声明事务

在遗留软件中混合编程事务和声明事务
EN

Stack Overflow用户
提问于 2016-02-11 14:07:02
回答 1查看 1.5K关注 0票数 9

我的问题涉及与混合编程和声明事务可能的并发问题。我正在开发一个遗留软件(Spring + Hibernate),它以编程的方式处理数据库连接和事务。

代码语言:javascript
复制
Session db = HibernateUtil.getSessionFactory().openSession();
db.beginTransaction();
// do stuff
db.getTransaction().commit();

该软件具有较新的模块,这些模块使用带有声明性事务的Spring数据体系结构(@ transactions )。在Microsoft SQL Server中,当从内部“手动”打开事务调用较新的Spring服务时,我们很少遇到数据库死锁。我认为问题在于有两个嵌套的事务读取/写入相同的表,导致死锁。

代码语言:javascript
复制
Session db = HibernateUtil.getSessionFactory().openSession();
db.beginTransaction();
// do stuff
springService.getStuff();
// do stuff
db.getTransaction().commit();

是否有一种方法可以安全地混合这些事务,或者在这两个事务中使用已经启动的事务?应该在调用Spring @Service/@Repository方法之前手动/以编程方式打开事务吗?Spring和HibernateUtil都使用相同的实体管理器进行数据库连接。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-02-11 16:50:16

当涉及到事务的行为时,声明性事务和编程/手动事务实际上没有区别。声明性事务使您能够以更加简洁和可读的方式划分事务边界,这就是全部。在幕后,Spring将执行手动启动和提交/回滚事务的相同操作。

我认为问题在于有两个嵌套的事务读取/写入相同的表,导致死锁。

很有可能。

是否有一种方法可以安全地混合这些事务,或者在这两个事务中使用已经启动的事务?

在特定的部分代码中这样做是否安全,这在很大程度上取决于代码所做的工作。如果嵌套的事务会导致死锁,那么它显然是不安全的,这与您如何获得嵌套事务没有任何关系(在拦截带有@Transactional(propagation = Propagation.PROPAGATION_REQUIRES_NEW)注释的方法时手动或Spring启动了它)。

在调用Spring @Service/@Repository方法之前,是否应该先关闭手动/以编程方式打开的事务?

再说一次,这取决于你需要解决什么。如果在嵌套事务完成后需要外部事务继续进行,则不应该这样做,否则可以。

TransactionTemplate是使用Spring手动启动事务的推荐方法,因为Spring随后会意识到事务边界,这意味着它将处理这样的事务,就像使用Spring注释以声明方式启动事务一样。

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

https://stackoverflow.com/questions/35341520

复制
相关文章

相似问题

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