REQUIRES_NEW: Spring 外部事务回滚也而不是在内部回滚时持久化

REQUIRES_NEW: Spring outer transaction rollbacks also instead of persisting when inner rollbacks

我有一个 Spring 引导应用程序,其中我在控制器和服务之间有一个薄层,它的唯一目的是尝试捕获,如果抛出异常,则使用 JpaRepository 保存失败的实体, 以便后续检查。 我设计了我的“拦截器”:

    @Transactional
    public void upload(byte[] bytes) {
       try {
          service.upload(bytes);
       } catch (Exception e) {
           failRepo.save(new Failure(bytes, e)); // code trimmed for brevity 
           throw e;
       }
   }

我的服务方法如下:

@Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class)
public void upload(byte[] bytes);

我期望的是,如果服务抛出异常,内部事务将被回滚,异常将弹出,外部事务将保留我的数据,但是休眠日志显示对于某些原因是外部事务也回滚并且失败数据未持久化。 我是否还需要外层的另一个传播级别?

编辑:相关日志

o.s.o.h.HibernateTransactionManager      : Creating new transaction with name [com.company.interceptor.upload]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT
o.s.o.h.HibernateTransactionManager      : Opened new Session [SessionImpl(480607911<open>)] for Hibernate transaction
o.h.e.t.internal.TransactionImpl         : On TransactionImpl creation, JpaCompliance#isJpaTransactionComplianceEnabled == false
o.h.e.t.internal.TransactionImpl         : begin
o.s.o.h.HibernateTransactionManager      : Exposing Hibernate transaction as JDBC [org.springframework.orm.hibernate5.HibernateTransactionManager$$Lambda17/0x0000000800d0c440@52318830]
o.s.o.h.HibernateTransactionManager      : Found thread-bound Session [SessionImpl(480607911<open>)] for Hibernate transaction
o.s.o.h.HibernateTransactionManager      : Suspending current transaction, creating new transaction with name [com.company.service.upload]
o.s.o.h.HibernateTransactionManager      : Opened new Session [SessionImpl(1041560268<open>)] for Hibernate transaction
o.h.e.t.internal.TransactionImpl         : On TransactionImpl creation, JpaCompliance#isJpaTransactionComplianceEnabled == false
o.h.e.t.internal.TransactionImpl         : begin
o.s.o.h.HibernateTransactionManager      : Exposing Hibernate transaction as JDBC [org.springframework.orm.hibernate5.HibernateTransactionManager$$Lambda17/0x0000000800d0c440@778c9da3]

------ other irrelevant for us logs

o.s.o.h.HibernateTransactionManager      : Initiating transaction rollback
o.s.o.h.HibernateTransactionManager      : Rolling back Hibernate transaction on Session [SessionImpl(1041560268<open>)]
o.h.e.t.internal.TransactionImpl         : rolling back
o.s.o.h.HibernateTransactionManager      : Closing Hibernate Session [SessionImpl(1041560268<open>)] after transaction
o.s.o.h.HibernateTransactionManager      : Resuming suspended transaction after completion of inner transaction
stomAnnotationTransactionAttributeSource : Adding transactional method 'save' with attribute: PROPAGATION_REQUIRED,ISOLATION_DEFAULT
o.s.o.h.HibernateTransactionManager      : Found thread-bound Session [SessionImpl(480607911<open>)] for Hibernate transaction
o.s.o.h.HibernateTransactionManager      : Participating in existing transaction
org.hibernate.engine.spi.ActionQueue     : Executing identity-insert immediately
org.hibernate.SQL                        : insert into failure_table (content_type, created_time, exception_message, bytes, user_agent) values (?, ?, ?, ?, ?)
o.h.id.IdentifierGeneratorHelper         : Natively generated identity: 15
o.h.r.j.i.ResourceRegistryStandardImpl   : HHH000387: ResultSet's statement was not registered
o.s.o.h.HibernateTransactionManager      : Initiating transaction rollback
o.s.o.h.HibernateTransactionManager      : Rolling back Hibernate transaction on Session [SessionImpl(480607911<open>)]
o.h.e.t.internal.TransactionImpl         : rolling back
o.s.o.h.HibernateTransactionManager      : Closing Hibernate Session [SessionImpl(480607911<open>)] after transaction

问题解决方案帮助找到:。

问题是 Spring 默认情况下会在运行时异常时回滚,所以我需要一个

@Transactional(noRollbackFor = Exception.class)

在我的拦截器上让它按照我的预期运行。