Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 当外部事务标记为回滚时回滚所有嵌套事务_Java_Spring_Transactions_Rollback_Propagation - Fatal编程技术网

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

Java 当外部事务标记为回滚时回滚所有嵌套事务,java,spring,transactions,rollback,propagation,Java,Spring,Transactions,Rollback,Propagation,我有两个带注释的方法。第二个方法被嵌套在第一个方法中的某个地方调用 现在,我希望发生以下行为: 每次输入第二个嵌套方法时,都会出现一个新的嵌套方法 应创建事务。当该事务被标记为 回滚,仅应回滚该事务 但是当 外部方法的事务标记为回滚,每个 内部嵌套事务-是否标记为回滚- 应该回滚 我必须如何设置值以实现此类功能 附言:我正在使用一个。你需要使用。请注意,此传播模式使用JDBC保存点来实现此行为,因此,只有当事务只是JDBC连接的包装器时,嵌套行为才有效。它不适用于JTA事务。有关更多详细信

我有两个带注释的方法。第二个方法被嵌套在第一个方法中的某个地方调用

现在,我希望发生以下行为:

  • 每次输入第二个嵌套方法时,都会出现一个新的嵌套方法 应创建事务。当该事务被标记为 回滚,仅应回滚该事务
  • 但是当 外部方法的事务标记为回滚,每个 内部嵌套事务-是否标记为回滚- 应该回滚
我必须如何设置值以实现此类功能



附言:我正在使用一个。你需要使用。请注意,此传播模式使用JDBC保存点来实现此行为,因此,只有当事务只是JDBC连接的包装器时,嵌套行为才有效。它不适用于JTA事务。有关更多详细信息,请参阅。

应该澄清Java事务中的默认行为。除非父事务提交,否则不会提交所有嵌套事务。请在此处阅读

我建议在单独的线程中实现此类功能,即您希望在嵌套事务中启动的方法—只需在单独的线程中启动它们即可。它可能看起来像以下伪代码:

//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);
}
//SomeService
//这里我们开始一个外部事务
@交易的
int processAllInTransaction(){
List jobIds=jobService.getJobs();
如果(!jobIds.isEmpty()){
新线程(newrunnable()){
@凌驾
公开募捐{
jobIds.forEach(jobId->
//执行外部事务中的所有内容
threadPool.execute(作业ID)
);
}
}).start();
} 
返回jobIds.size();
}
//执行人服务方式
作废执行(最终int作业ID){
tasks.add(taskExecutor.submit(new Runnable()){
无效运行(){
someProcessor.processJob(jobId);
}
}));
}
//另一服务的方法
@交易的
public void processJob(int jobId){
//这将在单独的thransaction中工作,因为它是在另一个Thread中执行的
someDao.doworkinternaltransaction(jobId);
}

如果您真的需要控制外部事务-在new Theread中的单个外部事务中执行嵌套事务工作,只需等待线程返回的结果,并在需要时抛出异常

HibernateTransactionManager
似乎也不完全支持嵌套事务,你知道在JTA下实现这种行为的方法吗?。我陷入了这个问题: