我正在为CMS
应用程序使用 Spring 3,JPA + Hibernate 。在该应用程序中,我有一个服务类方法,该方法使用带有@Transactional
属性的rollBack
注释进行注释。在该方法中,我使用循环将数据(即实体类)插入表中。对于每个iteration
循环,实体类必须保存到数据库中。但它没有发生。提交仅在循环执行完成并退出方法时发生。然后它立即提交并保存所有内容。但是,在这种情况下提交之前,我需要在数据插入数据库之前读取数据。我尝试使用ISOLATION LEVEL
来阅读未提交但由于我使用的是默认JPADialect
,因此无法支持。还尝试添加jpaDialect
的 hibernate 实现,但它仍然没有奏效。请帮助解决此问题。还有一件事,是否有任何方法使用传播所需的方法。
答案 0 :(得分:14)
你说得对,这是I
在acid中所代表的含义。由于事务处于隔离状态,因此其他事务在提交之前无法看到它们。但玩隔离级别是一种不好的做法。我宁愿建议你在内部启动和提交的单独事务中运行每一次迭代。
这在Spring中有点棘手,但这是一个例子:
public void batch() {
for(...) {
insert(...)
}
}
//necessarily in a different class!
@Transactional
public void insert() {
}
请注意,batch()
不使用@Transactional
进行注释,而insert()
必须位于不同的类(Spring服务)中。评论太久了,但这就是生活。如果您不喜欢它,可以手动使用TransactionTemplate
。
答案 1 :(得分:5)
使用循环删除方法上的事务注释。
在循环中调用一个单独的方法来执行保存,使该方法具有事务性
答案 2 :(得分:1)
您需要使用程序化事务(Spring的TransactionTemplate
或PlatformTransactionManager
是要查看的类,请参阅Spring Doc for programmatic transactions,或者您可以在循环中调用另一个事务方法事务用Propagation.REQUIRES_NEW
标记,意味着该方法的每次调用都在自己的事务中执行,请参阅here。我认为第二种方法要求您在不同的Spring bean上定义REQUIRES_NEW方法,因为AOP-Proxy。如果在事务中没有执行循环,你也可以省略REQUIRES_NEW。