Spring Boot @Transactional(propagation = Propagation.REQUIRES_NEW)不创建新事务,而是参与前一个事务

lqfhib0f  于 2023-08-04  发布在  Spring
关注(0)|答案(2)|浏览(145)

所有方法,methodA()、methodB()和logExceptionMethod()都在不同的bean中,

  1. @Transactional
  2. main method() {
  3. try{
  4. methodA();
  5. } catch(Exception e) {
  6. throw e;
  7. }
  8. }
  9. @Transactional(propagation = Propagation.REQUIRES_NEW)
  10. methodA(){
  11. try{
  12. methodB()
  13. }
  14. catch(Exception e) {
  15. throw e;
  16. }
  17. }
  18. methodB(){
  19. try {
  20. // api call
  21. }
  22. catch(Exception e) {
  23. logExceptionMethod();
  24. throw e;
  25. }
  26. }
  27. @Transactional(propagation = Propagation.REQUIRES_NEW)
  28. logExceptionMethod() {
  29. // create log entity
  30. // store entity in db
  31. }

字符串
现在,当API调用在methodB()try块中失败时,它将在catch中被捕获,然后logExceptionMethod()将被调用以记录异常,它正在尝试记录异常。但是事务在异常之后被回滚,并且根据参与现有事务的日志,没有为logExceptonMethod创建新的事务。
所以这个logExceptionMethod()在任何情况下都应该记录异常,因为它在一个没有异常的新事务中工作,但是由于methodB()中的异常,日志操作正在回滚?
这里不创建新事务的原因是什么,试图通过使methodB()也是Transactional(requires_new)来解决这个问题,但不起作用。那么,如何确保日志记录操作在任何情况下仍然有效呢?

mwg9r5ms

mwg9r5ms1#

这是一个正常的情况下,为什么你的日志不保存,因为Spring框架的事务基础设施代码标记一个事务,只有在运行时,未经检查的异常的情况下才回滚。
我认为您应该使用事务参数

  1. @Transactional(noRollbackFor="YourException.class")

字符串
我也建议你检查这个one

eit6fx6z

eit6fx6z2#

spring要求你抛出一个异常来被spring框架捕获,以便进行自动事务回滚。如果手动捕获异常,则需要手动回滚,您可以将其添加到异常处理中

  1. TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();

字符串
您还需要将其添加到事务中

  1. @Transactional(rollbackFor = Exception.class);

相关问题