@Transactional Annotation + for a data insertion in a loop

倾然丶 夕夏残阳落幕 提交于 2019-12-21 05:31:26

问题


I am using Spring 3, JPA + Hibernate for a CMS application. In that application I have a service class method which is annotated with @Transactional Annotation with rollBack property. Inside that method I am inserting data (ie entity classes) to a table using a loop. For each iteration of the loop entity classes has to be saved to the database. But it is not happening. The commit only happens when the execution of the loop has completed and exits from the method. Then it commits and saves all at once. But I need to read data once it gets inserted into the database before committing in this case. I tried with the ISOLATION LEVEL to read uncommitted but it didn't supported since I am using the default JPADialect. Also tried to add the hibernate implementation of jpaDialect but still it didn't worked. Please help with a workaround for this problem. One more thing, is there any way using propagation required method.


回答1:


remove the transactional annoation on the the method with loop.

In the loop call a separate method to perform the save, make that method transactional




回答2:


You are right, this is what I stands for in acid. Because the transactions are working in isolation, other transactions cannot see them before they are committed. But playing with isolation levels is a bad practice. I would rather advice you to run each and every iteration in a separate transaction with start and commit inside.

This is a bit tricky in Spring, but here is an example:

public void batch() {
    for(...) {
        insert(...)
    }
}

//necessarily in a different class!
@Transactional
public void insert() {

}

Note that batch() is not annotated with @Transactional and insert() has to be in a different class (Spring service). Too long to comment, but that's life. If you don't like it, you can use TransactionTemplate manually.




回答3:


You either need to go with programmatic transactions (Spring's TransactionTemplate or PlatformTransactionManager are the classes to look at, see Spring Doc for programmatic transactions, or you can call another transactional method from within your loop where the transaction is marked with Propagation.REQUIRES_NEW, meaning each call of that method is executed in its own transaction, see here. I think that the second approach requires you to define the REQUIRES_NEW method on a different Spring bean because of the AOP-Proxy. You can also omit the REQUIRES_NEW if the loop is not executed within a transaction.



来源:https://stackoverflow.com/questions/9721004/transactional-annotation-for-a-data-insertion-in-a-loop

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!