我有两种方法用@Transactional
. 第二种方法被称为嵌套在第一种方法中的某个地方。
现在我希望发生以下行为:
- 每次进入第二个嵌套方法时,都应该创建一个新的嵌套事务。当那个事务被标记为回滚时,只有那个事务应该被回滚。
- 但是当外部方法的事务被标记为回滚时,内部的每个嵌套事务——无论它是否被标记为回滚——都应该被回滚。
我如何设置Propagation
值才能实现这样的功能?
PS:我正在使用HibernateTransactionManager。
我有两种方法用@Transactional
. 第二种方法被称为嵌套在第一种方法中的某个地方。
现在我希望发生以下行为:
我如何设置Propagation
值才能实现这样的功能?
PS:我正在使用HibernateTransactionManager。
One should clarify the default behaviour in Java Transactions. All nested transaction will not commit unless the parent commits. Read about it here http://en.wikibooks.org/wiki/Java_Persistence/Transactions
我建议在单独的线程中实现此类功能,即您希望在嵌套事务中启动的方法 - 只需在单独的线程中启动它们。它可能看起来像下面的伪代码:
//SomeService
// Here we start an external transaction
@Transactional
int processAllInTransaction() {
List<Integer> jobIds = jobService.getJobs();
if (!jobIds.isEmpty()) {
new Thread(new Runnable() {
@Override
public void run() {
jobIds.forEach(jobId ->
//Execute eveything in external transaction
threadPool.execute(jobId)
);
}
}).start();
}
return jobIds.size();
}
//Method of Executor Service
void execute(final int jobId) {
tasks.add(taskExecutor.submit(new Runnable() {
void run() {
someProcessor.processJob(jobId);
}
}));
}
//Method of another Service
@Transactional
public void processJob(int jobId) {
//this will work in separate thransaction since was executed in another Theread
someDao.doWorkInExternalTransaction(jobId);
}
如果您确实需要控制外部事务 - 在 new Theread 中的单个外部事务中执行嵌套事务工作,只需等待 Thread 的返回结果并在需要时抛出异常