gpt4 book ai didi

java - 在遗留软件中混合编程式和声明式事务

转载 作者:塔克拉玛干 更新时间:2023-11-03 03:48:15 24 4
gpt4 key购买 nike

我的问题是关于混合程序性和声明性事务可能出现的并发问题。我正在开发一个以编程方式处理数据库连接和事务的遗留软件(Spring + Hibernate)。

Session db = HibernateUtil.getSessionFactory().openSession();
db.beginTransaction();
// do stuff
db.getTransaction().commit();

该软件具有更新的模块,这些模块使用带有声明式事务 (@Transactional) 的 Spring 数据架构。当从“手动”打开的事务中调用较新的 Spring 服务时,我们在极少数情况下遇到过 Microsoft SQL Server 数据库死锁。我认为问题是有两个嵌套事务读取/写入相同的表导致死锁。

Session db = HibernateUtil.getSessionFactory().openSession();
db.beginTransaction();
// do stuff
springService.getStuff();
// do stuff
db.getTransaction().commit();

有没有办法安全地混合这些交易或在两者中使用已经开始的交易?我应该在调用 Spring @Service/@Repository 方法之前关闭手动/以编程方式打开的事务吗? Spring 和 HibernateUtil 都使用相同的实体管理器进行数据库连接。

最佳答案

当涉及到交易行为时,声明式和程序化/手动交易之间确实没有区别。声明式事务使您能够以更简洁和可读的方式划定事务边界,仅此而已。在幕后,Spring 将执行与手动启动和提交/回滚事务相同的操作。

I think the problem is that there are two nested transactions reading/writing same tables causing deadlocks.

很有可能。

Is there a way to mix these transactions safely or use the already started transaction in both?

在您的特定零件代码中执行此操作是否安全很大程度上取决于代码的作用。如果嵌套事务会导致死锁,那显然是不安全的,这与你如何获得嵌套事务无关(手动或Spring在拦截用注释的方法时启动它@Transactional(propagation = Propagation.PROPAGATION_REQUIRES_NEW) )。

Should I just close the manually/programmatically opened transaction before calling Spring @Service/@Repository methods?

同样,这取决于您需要解决的问题。如果您需要在嵌套事务完成后继续进行外部事务,那么您不应该这样做。否则你可以。

TransactionTemplate是使用 Spring 手动启动事务的推荐方法,因为 Spring 然后知道事务边界,这意味着它将像对待使用 Spring 注释以声明方式启动的事务一样对待此类事务。

关于java - 在遗留软件中混合编程式和声明式事务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35341520/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com