简体   繁体   English

Spring Transaction没有回滚

[英]Spring Transaction not rolling back

I have something like this: 我有这样的事情:

@Service
@Transactional
public class ServiceA {

    @Autowired
    SomeDAO1 dao1; 

    @Autowired
    ServiceB serviceB;

    public void methodServiceA() {

        serviceB.someMethodThatRunsInsertIntoDB(); 
        dao1.anotherMethodThatRunsInsertIntoDB(); 

    }

}

@Service
@Transactional
public class ServiceB {

     @Autowired
     Dao2 dao2;

     public void someMethodThatRunsInsertIntoDB() {
          dao2.insertXXX();
     }

}

My problem is: if serviceB.someMethodThatRunsInsertIntoDB() executes sucessfully but dao1.anotherMethodThatRunsInsertIntoDB() throw an exception, the changes made by serviceB are not rolled back. 我的问题是:如果serviceB.someMethodThatRunsInsertIntoDB()执行成功但dao1.anotherMethodThatRunsInsertIntoDB()抛出异常,则不会回滚serviceB所做的更改。 I need to rollback those changes in case an exception occur in dao1.anotherMethodThatRunsInsertIntoDB() . 如果在dao1.anotherMethodThatRunsInsertIntoDB()发生异常,我需要回滚这些更改。 How can I do this? 我怎样才能做到这一点?

// EDITED //已编辑

Transaction configuration in spring-servlet.xml spring-servlet.xml中的事务配置

<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
    <property name="entityManagerFactory" ref="entityManagerFactory" />
    <property name="jpaDialect">
        <bean class="org.springframework.orm.jpa.vendor.HibernateJpaDialect" />
    </property>
</bean>

Is it relevant if one dao uses an EntityManager and the other dao uses JdbcTemplate to interact with DB? 如果一个dao使用EntityManager而另一个dao使用JdbcTemplate与DB交互是否相关?

//UPDATE -- EntityManager configuration // UPDATE - EntityManager配置

<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="dataSource" ref="dataSource" />
    <property name="jpaVendorAdapter">
        <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
            <property name="showSql" value="true" />
            <property name="generateDdl" value="true" />
        </bean>
    </property>

you need to pass rollbackFor parameter with type of your checked exception. 你需要传递rollbackFor参数与您检查的异常的类型。 It seems that spring rollbacks only on unchecked exceptions by default. 看起来Spring默认只在未经检查的异常上回滚。 More details: Spring transaction: rollback on Exception or Throwable 更多细节: Spring事务:在Exception或Throwable上回滚

你需要在spring配置文件中使用<tx:annotation-driven/>来启用注释驱动的事务管理。

It's because your dao1.anotherMethodThatRunsInsertIntoDB() call does not support current transaction (ServiceA transaction). 这是因为您的dao1.anotherMethodThatRunsInsertIntoDB()调用不支持当前事务(ServiceA事务)。

You need to use below propagation level in your ServiceB class. 您需要在ServiceB类中使用低于传播级别。

@Service
@Transactional(propagation = Propagation.REQUIRED)
public class ServiceB {

REQUIRED: Spring REQUIRED behavior means that the same transaction will be used if there is an already opened transaction in the current bean method execution context. 要求: Spring REQUIRED行为意味着如果当前bean方法执行上下文中已经打开的事务,将使用相同的事务。 Create a new one if none exists. 如果不存在,则创建一个新的。 In short this means that if an inner(2nd Transaction) method causes a transaction to rollback, the outer(1st Transaction) method will fail to commit and will also rollback the transaction. 简而言之,这意味着如果内部(第二个事务)方法导致事务回滚,则外部(第一个事务)方法将无法提交并且还将回滚事务。

Propagation Means: Typically, all code executed within a transaction scope will run in that transaction. 传播方式:通常,在事务范围内执行的所有代码都将在该事务中运行。 However, you have the option of specifying the behavior in the event that a transactional method is executed when a transaction context already exists. 但是,您可以选择在事务上下文已存在时执行事务方法时指定行为。 For example, code can continue running in the existing transaction (the common case); 例如,代码可以继续在现有事务中运行(常见情况); or the existing transaction can be suspended and a new transaction created. 或者可以暂停现有交易并创建新交易。 Spring offers all of the transaction propagation options familiar from EJB CMT. Spring提供了EJB CMT中熟悉的所有事务传播选项。 To read about the semantics of transaction propagation in Spring, see Transaction Propagation 要阅读有关Spring中事务传播的语义,请参阅事务传播

Edited 编辑
Note: The only exceptions that set a transaction to rollback state by default are the unchecked exceptions (like RuntimeException). 注意:默认情况下,将事务设置为回滚状态的唯一例外是未经检查的异常(如RuntimeException)。 If you want checked exceptions to also set transactions to rollback you must configure them to do so, eg. 如果您希望已检查的异常也将事务设置为回滚,则必须将它们配置为执行此操作,例如。

@Service
@Transactional(propagation = Propagation.REQUIRED, rollbackFor = YourCheckedException.class))
public class ServiceA {

Note: As I noticed, declarative transaction management is AOP based. 注意:正如我所注意到的,声明式事务管理是基于AOP的。 This means that Spring wraps the transactional beans into a transactional proxy, which takes care of starting and committing transactions. 这意味着Spring将事务bean包装到事务代理中,该代理负责启动和提交事务。 This means that the method call must be intercepted by the proxy in order to be transactional. 这意味着必须由代理拦截方法调用才能成为事务性的。 You need to make sure below config had in your Spring configuration file. 您需要在Spring配置文件中确保以下配置。

<tx:annotation-driven transaction-manager="transactionManager" />

My first suggestion is to use @Transactional annotation on method level if it is really not needed on class level. 我的第一个建议是在方法级别使用@Transactional注释,如果在类级别上真的不需要它。

Second thing, try use javax.transaction.Transactional annotation instead of org.springframework.transaction.annotation.Transactional , Spring will automatically handle the propagation. 第二件事,尝试使用javax.transaction.Transactional注释而不是org.springframework.transaction.annotation.Transactional ,Spring会自动处理传播。

You also need to enable transaction management before using @Transactional , Using Spring Boot we can simply do that by marking Application class by @EnableTransactionManagement . 您还需要在使用@Transactional之前启用事务管理,使用Spring Boot我们可以通过@EnableTransactionManagement标记Application类来@EnableTransactionManagement

However, you can surely do this by XML configuration ( <tx:annotation-driven /> ) as well if you want to. 但是,如果您愿意,您也可以通过XML配置( <tx:annotation-driven /> )来完成此操作。 Read http://docs.spring.io/spring-data/jpa/docs/1.11.0.M1/reference/html/#transactions for more details 阅读http://docs.spring.io/spring-data/jpa/docs/1.11.0.M1/reference/html/#transactions了解更多详情

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM