Commit during transaction in @Transactional

24,539

Solution 1

No, you need to do it programatically using, for instance, the TransactionTemplate API. Read more here.

It would look something like

while (it.hasNext())
{
    transactionTemplate.execute(new TransactionCallbackWithoutResult() {
        protected void doInTransactionWithoutResult(TransactionStatus status) {
            int counter = 0;
            while (it.hasNext() && counter++ < 500) {
                Member wsBean = it.next();
                em.persist(wsBean);
                log.info("Webservices record " + wsBean + " saved. " + i++);
            }
        }
    );
}

Solution 2

Your question suggests that you have misplaced your transaction boundary.

You can move the persist call into a private method and make that method transactional instead of the outer one. This method could accept 500 members at a time and then will commit when it exits.

Solution 3

If you are looking forward to committing transactionally inside your other transaction, you might need to use @Transactional (propagation = Propagation.REQUIRES_NEW)

Share:
24,539
Michael Z
Author by

Michael Z

Micro SAAS Bootstrapper with primary focus on Shopify.

Updated on July 09, 2022

Comments

  • Michael Z
    Michael Z almost 2 years

    Is that possible to perform commit in the method that is marked as Spring's @Transactional?

    @PersistenceContext
    private EntityManager em;
    
    @Transactional(propagation = Propagation.REQUIRED)
    public void saveMembersWithMultipleCommits(List<Member> members)
        throws HibernateException
    {
        Iterator<Member> it = members.iterator();
        while (it.hasNext())
        {
            while (it.hasNext())
            {
                Member wsBean = it.next();
                em.persist(wsBean); // overall commit will be made after method exit
                log.info("Webservices record " + wsBean + " saved. " + i++);
            }
        }
    }
    

    I would like to have commit to DB after say each 500 items. Is that possible with aforementioned context?

  • Michael Z
    Michael Z over 11 years
    Will I have the new one connection to DB be opened for second @Transactional method invocation or it will be the same connection?
  • Michael Z
    Michael Z over 11 years
    So I will have a new connection to DB for each callback?
  • Matin Kh
    Matin Kh over 11 years
    This is a totally separated transaction but the connection is the same. Check it for yourself. I might be making a mistake.
  • pap
    pap over 11 years
    @MichaelZ no, just a new transaction.
  • Michael Z
    Michael Z over 11 years
    And what is hibernateTemplate here? What class?
  • vsingh
    vsingh over 11 years
    Sorry. should have clarified. I am giving example of spring with hibernate and using hibernateTemplate. You are using EntityManager which is with JPA and can use that. You can do this Session session = entityManager.unwrap(Session.class); The session is hibernate session
  • pap
    pap over 11 years
    Requires load-time or compile-time weaving, won't work with Springs "standard" proxy-based weaving.
  • Jess
    Jess over 3 years
    which version of hibernate ? Does EntityManager of JPA has hibernateTemplate ?