afterCommit 在整个事务完成之前调用

问题描述 投票:0回答:1

我也有这样的情况

@Component
@Slf4j
public class MainClass {

    @Autowired
    private SomeService service;

    @Autowired
    private OtherService otherService;

    @Transactional
    private Object save() {
        List<Object> objects = processSomething();
        return otherService.save(objects);
    }

    private List<Object> processSomething() {
        return service.doSomething();
    }
}

@Service
@Transactional
@Slf4j
public class SomeService {

    @Autowired
    private SomeService service;

    public Object doSomething() {
        List<Object> objects = List.of(new Object());
        doSomethingAfterCommit();
        return objects;
    }

    private void doSomethingAfterCommit() {
        if (!TransactionSynchronizationManager.isActualTransactionActive()) return;

        TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() {
            @Override
            public void afterCommit() { // triggered before otherService.save() call
                // some db operations to find records saved in otherService.save()
            }
        });
    }
}

@Service
@Transactional
@Slf4j
public class OtherService {

    public Object save(List<Object> objects) {
        // db operations to save all entities and returns one
    }
}

我很困惑为什么在 OtherService 的 save 方法启动之前就调用 doSomethingAfterCommit 中的 afterCommit 。根据我设置事务注释的方式,我认为所有数据库操作都将成为同一事务的一部分,因此 afterCommit 将在 MainClass.save() 结束时调用。为什么没有发生?

java spring spring-boot jpa spring-transactions
1个回答
0
投票

如果您检查事务文档传播文档,您将看到当您有

@Transactional
注释时,默认传播(
REQUIRED
)已启用。这意味着,在像您这样的情况下,您有嵌套的事务层,下一层将使用上一层中已经存在的事务。

如果您有多种具有不同事务的级联方法,您应该根据数据库文档探索(因为并非所有数据库的所有版本都允许嵌套事务)

@Transactional(propagation = Propagation.NESTED)
@Transactional(propagation = Propagation.REQUIRES_NEW)

© www.soinside.com 2019 - 2024. All rights reserved.