@Transactional Annotation + for data entry in a loop

I am using Spring 3, JPA + Hibernate for an application CMS

. In this application, I have a service class method that is annotated with @Transactional

Annotate with a property rollBack

. Inside this method I am inserting data (i.e. entity classes) into the table using a loop. For each iteration

entity class, the entities must be stored in the database. But that doesn't happen. Committing occurs only when the loop is finished and the method exits. Then it captures and saves everything at once. But I need to read the data as soon as it is inserted into the database, before committing in this case. I tried with ISOLATION LEVEL

read uncommitted, but it was not supported since I am using the default JPADialect

. Also tried adding the implementationhibernate JPADialect

, but still it didn't work. Please help with a workaround for this issue. One more thing, is there any way to use the method that requires propagation.

+3


source to share


3 answers


remove the transactional annotation in a looping method.



Within the loop, call a separate method to perform the save, make this method transactional

+5


source


You're right, that's what acidI

means . Because the transactions operate in isolation, other transactions cannot see them until they are committed. But playing with isolation levels is bad practice. I would advise you to run each iteration in a separate transaction with start and commit inside.

It's a little tricky in Spring, but here's an example:



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

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

}

      

Please note that it is batch()

not , annotated @Transactional

and insert()

must be in another class (Spring). Too long to comment, but what a life. If you don't like it, you can use TransactionTemplate

manually.

+11


source


You either need to go with programmatic transactions (Spring TransactionTemplate

, or PlatformTransactionManager

- these are the classes to look at, see the Spring Doc for programmatic transactions, or you can call another transactional method from your loop where the transaction is marked Propagation.REQUIRES_NEW

, i.e. every call to that method is done in its own transaction. see here . I think that for the second approach, you need to determine REQUIRES_NEW method to other Spring bean for AOP-Proxy. you can also omit REQUIRES_NEW, if the cycle is not executed within a transaction.

+1


source







All Articles