I have a @Transactional
method which invokes another method on a common spring bean, that has long been used to perform batch
operations, across mappers. The problem now is that, if there is an error in the @Transactional
method, the DMLs executed on the batch
are not rolled back, as they were executed on a different session, with it's own transaction.
public class HamsterRepo{
...
@Autowired
BatchOperationBean<Hamsters> idioticBatchBean;
@Transactional
public void saveHamsters(List<Hamsters> hams){
idioticBatchBean.executebatch("saveHamsters", hams);
}
}
public class BatchOperationBean<T>{
@Autowired
SqlSessionFactory sqlFactory;
public void executebatch(String mapperId, List<T> ts){
SqlSession sqlSession =
this.sqlSessionFactory.openSession(ExecutorType.BATCH,
TransactionIsolationLevel.SERIALIZABLE);
try(sqlSession){
for(T t in ts){
sqlSession.update(mapperId , t);
}
sqlSession.commit();
// Clean Up stuff and Exception Handling...
}
}
}
Now, Is there a way to relate the two Spring Tx and SqlSessionFactory
? Will injecting SqlSession, instead of the factory help? Or is there a way to obtain the SqlSession from Spring Tx? Or a way in Spring to identify & execute queries across mappers without an SqlSesion?
PS: Using Spring 4.1.7, Mybatis: 3.4.4, Mybatis-spring : 1.3.1
Looks like the the way to link Spring Transaction and Mybatis SqlSession is the SqlSessionTemplate
Thread safe, Spring managed, SqlSession that works with Spring transaction management to ensure that that the actual SqlSession used is the one associated with the current Spring transaction. In addition, it manages the session life-cycle, including closing, committing or rolling back the session as necessary based on the Spring transaction configuration.