需要新的:spring外部事务回滚,而不是在内部回滚时持久化

fcwjkofz  于 2021-07-16  发布在  Java
关注(0)|答案(1)|浏览(397)

我有一个spring-boot应用程序,在控制器和服务之间有一个薄层,它的唯一目的是尝试捕获,如果抛出异常,用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);

我所期望的是,在服务中抛出异常的情况下,内部事务将被回滚,异常将弹出,外部事务将持久化我的数据,但是hibernate日志显示,由于某种原因,外部事务也会回滚,失败数据不会持久化。我还需要在外层上的另一个传播级别吗?
编辑:相关日志

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$$Lambda$1317/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$$Lambda$1317/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
lqfhib0f

lqfhib0f1#

问题解决方案可通过以下方式找到:https://stackoverflow.com/a/7125918/3214777.
问题是spring在运行时异常时默认回滚,所以我需要一个

@Transactional(noRollbackFor = Exception.class)

在我的拦截器上让它像我预期的那样运行。

相关问题