0
我有这种方法遍历列表并调用存储过程。它运行良好。在多线程进程中运行存储过程
@Transactional(propagation = Propagation.SUPPORTS)
public class SomeService{
@Autowired
MyJpaConfiguration myJpaConfiguration ;
private String runProcedure(...){
for (int j = 0; j < size; j++) {
EntityManager entityManager = myJpaConfiguration.mainUnitEM();
Query query = entityManager.createNativeQuery("CALL PROCEDURE(params...)");
query.setParameter(...);
query.executeUpdate();
}
}
}
现在,为了加快这一进程,我希望做同样的事情,但在并行调用,所以我的代码变得
@Transactional(propagation = Propagation.SUPPORTS)
public class SomeService{
@Autowired
MyJpaConfiguration myJpaConfiguration ;
private String runProcedure(...){
ListeningExecutorService executor = MoreExecutors.listeningDecorator(Executors.newCachedThreadPool());
for (int j = 0; j < size; j++) {
executor.submit(new Callable<String>(){
public String call() throws Exception {
EntityManager entityManager = myJpaConfiguration.mainUnitEM();
Query query = entityManager.createNativeQuery("CALL PROCEDURE(params...)");
query.setParameter(...);
query.executeUpdate();
return "Ok";
}
});
}
}
}
并行运行的代码时,我的问题是,我得到这个错误:
javax.persistence.TransactionRequiredException: Executing an update/delete query
据我所知,由于某种原因,新的线程没有找到当前事务上下文所以我手动企图以
开始交易entityManager.getTransaction().begin();
...
entityManager.getTransaction().commit();
,但我得到
A JTA EntityManager cannot use getTransaction()
这使得SENS因为它是一个容器管理事务。
在这一点上,我只是不知道如何在多线程环境中管理事务。
我对JTA使用Spring3.2,Hibernate 3.6,atomikos 3.8。
这个答案将解决你的问题,但它不能解释为什么。请注意,JPA会话是_NOT_线程安全的,Spring管理事务是线程爆炸。 – lscoughlin