4

我有两种方法用@Transactional. 第二种方法被称为嵌套在第一种方法中的某个地方。

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

  • 每次进入第二个嵌套方法时,都应该创建一个新的嵌套事务。当那个事务被标记为回滚时,只有那个事务应该被回滚。
  • 但是当外部方法的事务被标记为回滚时,内部的每个嵌套事务——无论它是否被标记为回滚——都应该被回滚。

我如何设置Propagation值才能实现这样的功能?


PS:我正在使用HibernateTransactionManager

4

3 回答 3

4

您需要使用NESTED。请注意,此传播模式使用 JDBC SavePoints 来实现此行为,因此嵌套行为仅在事务只是 JDBC 连接的包装器时才有效。它不适用于 JTA 事务。有关更多详细信息,请参阅Spring 文档

于 2012-06-25T17:06:13.960 回答
1

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

于 2014-02-14T17:20:22.003 回答
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);
}

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

于 2016-11-15T18:23:58.067 回答