当外部事务标记为回滚时,回滚所有嵌套事务。

4
我有两个方法用 @Transactional 进行注释。第二个方法在第一个方法的某个嵌套位置被调用。
现在我想要实现以下行为:
  • 每次进入第二个嵌套方法时,都应该创建一个新的嵌套事务。当该事务标记为回滚时,只有该事务应该回滚。
  • 但是当外部方法的事务被标记为回滚时,内部的每个嵌套事务 —— 无论它是否被标记为回滚 —— 都应该回滚。
如何设置 Propagation 值以实现这样的功能?

附言:我正在使用一个HibernateTransactionManager

3个回答

4
你需要使用 NESTED。请注意,此传播模式使用JDBC SavePoints以实现此行为,并且嵌套行为仅在事务仅是JDBC连接的包装器时才起作用。对于JTA事务,它不起作用。有关更多详细信息,请参见Spring文档

似乎HibernateTransactionManager也不完全支持嵌套事务。 - user321068
JB Nizet,您知道在JTA下如何实现该行为吗?我被这个问题困扰着:https://dev59.com/214c5IYBdhLWcg3wSIrf - codependent

1

0
我建议在单独的线程中实现这样的功能,即您想要在嵌套事务中启动的方法 - 只需在单独的线程中启动它们。 它可能看起来像以下伪代码:
//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);
}

如果您确实需要控制外部事务 - 可以在新线程中执行嵌套事务工作,并等待从线程返回的结果,如有必要则抛出异常


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接