@Transactional Annotation +用于循环中的数据插入

时间:2012-03-15 13:46:37

标签: spring hibernate jpa transactions

我正在为CMS应用程序使用 Spring 3,JPA + Hibernate 。在该应用程序中,我有一个服务类方法,该方法使用带有@Transactional属性的rollBack注释进行注释。在该方法中,我使用循环将数据(即实体类)插入表中。对于每个iteration循环,实体类必须保存到数据库中。但它没有发生。提交仅在循环执行完成并退出方法时发生。然后它立即提交并保存所有内容。但是,在这种情况下提交之前,我需要在数据插入数据库之前读取数据。我尝试使用ISOLATION LEVEL来阅读未提交但由于我使用的是默认JPADialect,因此无法支持。还尝试添加jpaDialect hibernate 实现,但它仍然没有奏效。请帮助解决此问题。还有一件事,是否有任何方法使用传播所需的方法。

3 个答案:

答案 0 :(得分:14)

你说得对,这是I中所代表的含义。由于事务处于隔离状态,因此其他事务在提交之前无法看到它们。但玩隔离级别是一种不好的做法。我宁愿建议你在内部启动和提交的单独事务中运行每一次迭代。

这在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的TransactionTemplatePlatformTransactionManager是要查看的类,请参阅Spring Doc for programmatic transactions,或者您可以在循环中调用另一个事务方法事务用Propagation.REQUIRES_NEW标记,意味着该方法的每次调用都在自己的事务中执行,请参阅here。我认为第二种方法要求您在不同的Spring bean上定义REQUIRES_NEW方法,因为AOP-Proxy。如果在事务中没有执行循环,你也可以省略REQUIRES_NEW。