Commit transaction to @Transactional

Is it possible to execute commit on a method marked as Spring @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 fix the DB after every 500 points say. Is this possible in the above context?

+4
source share
4 answers

No, you need to do this programmatically using, for example, the TransactionTemplate API. More details here .

He would look 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++); } } ); } 
+5
source

Your question suggests that you miss the boundary of your transaction.

You can move the persist call to a private method and make this method transactional rather than external. This method can accept 500 members at a time, and then will be committed when it comes out.

+5
source

If you expect to complete a transaction within your other transaction, you may need to use @Transactional (propagation = Propagation.REQUIRES_NEW)

+1
source

An alternative strategy is to create a method in the DAO and mark it with @Transactional. This method will perform a bulk update (for example, 500 ns). So you can have a method with code

 @Transactional public void mybatchUpdateMethod(){ StatelessSession session = this.hibernateTemplate.getSessionFactory() .openStatelessSession(); Transaction transaction = null; Long entryCounter = 0L; PreparedStatement batchUpdate = null; try { transaction = session.beginTransaction(); batchUpdate = session.connection().prepareStatement(insertSql); for (BatchSnapshotEntry entry : entries) { entry.addEntry(batchUpdate); batchUpdate.addBatch(); if (++entryCounter == 500) { // Reached limit for uncommitted entries, so commit batchUpdate.executeBatch(); } } batchUpdate.executeBatch(); batchUpdate.close(); batchUpdate = null; } catch (HibernateException ex) { transaction.rollback(); transaction = null; } } 

Each time you call this method, it commits after 500 inserts / updates

0
source

Source: https://habr.com/ru/post/1439842/


All Articles