【问题标题】:Rolling back transactions on checked and unchecked exceptions回滚已检查和未检查异常的事务
【发布时间】:2011-11-05 18:45:05
【问题描述】:

我将 Spring JDBC 模板与 PostgreSQL 一起使用。下面是我的配置 数据源和事务设置:

<bean id="databasePropertyConfigurer"
          class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
          p:location="/WEB-INF/config/database.properties" />

    <bean id="dataSource"
          class="org.springframework.jdbc.datasource.DriverManagerDataSource"
          p:driverClassName="${database.driverClassName}"
          p:url="${database.url}"
          p:username="${database.username}"
          p:password="${database.password}" />

    <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>

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

在我的业务层中,我正在执行以下操作:

@Transactional(rollbackFor=Exception.class)
@RequiresPermissions("hc:patient_createInvoice")
public Long createInvoice(Invoice invoice, List<InvoiceItem> items) throws ValidationException, NetAmountMismatchException, PatientInvoiceException
{
       try{
            dao1.insert(invoice);
       }
       catch(DataAccessException x){
            throw new PatientInvoiceException(x);
       }

       try{
            somevalidation(invoiceItem);    // Causes validation exception
            dao2.insert(invoiceItems);
       }
       catch(DataAccessException x){
       throw new PatientInvoiceException(x);
   }
}

类似的东西。我需要的是,每当此方法抛出任何异常(选中或未选中)时,到目前为止执行的所有数据库更新都应该滚动。

当前代码不会发生这种情况。

我实际上错过了什么?

【问题讨论】:

    标签: spring postgresql jdbctemplate spring-jdbc


    【解决方案1】:

    默认情况下,Spring 只回滚 unchecked 异常的事务。来自Spring reference manual:

    Spring Framework 的事务基础架构代码只在运行时、未检查异常的情况下将事务标记为回滚; [...] 从事务方法抛出的已检查异常不会导致默认配置回滚。

    但是,您也可以将 Spring 配置为回滚已检查的异常,例如:

    <tx:advice id="txAdvice">
        <tx:attributes>
            <tx:method name="*" rollback-for="ValidationException, NetAmountMismatchException, PatientInvoiceException" />
        </tx:attributes>
    </tx:advice>
    

    【讨论】:

    • 抱歉,回复有点晚了。在这种情况下,@Transactional(rollbackFor=Exception.class) 到底有什么用?我的理解是,如果我给出 rollbackFor=Exception.class,Exception 和子类将成为回滚的候选对象。
    • 对不起,我错过了。你是对的,rollbackFor 本质上是我在 XML 声明中使用的 rollback-for 的注释等效项,有关详细信息,请参阅reference docs。
    • 没错。但是,使用上面提到的代码,事务并没有回滚。它部分地提交给数据库。上面提到的所有异常类都是从 RuntimeException 派生的。任何的想法?我还需要做 AOP 的事情吗?
    猜你喜欢
    • 2021-02-22
    • 1970-01-01
    • 2012-08-20
    • 2013-05-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多