【问题标题】:Spring transaction fail rollbackSpring事务失败回滚
【发布时间】:2016-11-06 14:07:42
【问题描述】:

我遇到了一个问题“Spring 事务失败回滚”。我有一个调用 2 DAO 将数据插入数据库表的服务类。

emTrcvLineDAO.create(lineVo) 由于 lineVo 缺少一些必填字段而无法插入到表中,但是 emTrcvHeaderDAO.create(vo) 回滚失败并且数据仍然成功插入到数据库中。我想知道为什么它不回滚,因为两个 DAO 在同一个事务中。

有人对此有想法吗?提前致谢。

 public void saveEmTrcvHeader(List<EmTrcvHeaderVOImpl> voList,  List<ResponseItem> responseItemList) {

        for (EmTrcvHeaderVOImpl vo : voList) {
            emTrcvHeaderDAO.create(vo);
            List<EmTrcvLineVOImpl> lineList = vo.getLineList();
            for (int i = 0; i < lineList.size(); i++) {
                EmTrcvLineVOImpl lineVo = lineList.get(i);
                lineVo.setEmTrcvHeaderId(vo.getEmTrcvHeaderId());
                lineVo.setProjId(null);
                emTrcvLineDAO.create(lineVo);

            }    

        }       

}

我的交易配置:

<bean id="txProxyTemplate" abstract="true" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
    <property name="transactionManager">
        <ref bean="transactionManager" />
    </property>
    <property name="proxyTargetClass">
        <value>true</value> 
    </property>
    <property name="transactionAttributes">
        <props>             
            <prop key="save*">PROPAGATION_REQUIRED,-java.lang.Exception,-org.springframework.dao.DataAccessException</prop>     
            <prop key="*">PROPAGATION_REQUIRED,-java.lang.Exception,-org.springframework.dao.DataAccessException</prop>
        </props>
    </property>
</bean>

我的服务和 dao 定义如下:

<bean name="emTrcvHeaderService" parent="txProxyTemplate">
    <property name="target">
      <bean class="com.emtrcv.service.EmTrcvHeaderService">
        <property name="emTrcvHeaderDAO">
          <ref bean="emTrcvHeaderDAO"/>
        </property>
         <property name="emTrcvPubSelectIdsDAO">
          <ref bean="emTrcvPubSelectIdsDAO"/>
        </property>
        <property name="emTrcvLineDAO">
          <ref bean="emTrcvLineDAO"/>
        </property>
      </bean>
    </property>
  </bean>
  <bean name="emTrcvHeaderDAO" class="com.emtrcv.dao.EmTrcvHeaderDAOImpl">
    <property name="sessionFactory" ref="sessionFactory"/>
  </bean>
  <bean name="emTrcvPubSelectIdsDAO" class="com.emtrcv.dao.EmTrcvPubSelectIdsDAOImpl">
    <property name="sessionFactory" ref="sessionFactory"/>
  </bean>
   <bean name="emTrcvLineDAO" class="com.emtrcv.dao.EmTrcvLineDAOImpl">
    <property name="sessionFactory" ref="sessionFactory"/>
  </bean>

【问题讨论】:

  • emTrcvHeaderDAO.create(vo) 应该回滚,因为 emTrcvLineDAO.create(lineVo) 失败并抛出 org.springframework.dao.DataIntegrityViolationException ,但实际上 emTrcvHeaderDAO.create(vo) 不回滚并且 vo 数据仍然被插入到数据库中。为什么?
  • saveEmTrcvHeader() 是 emTrcvHeaderService 服务 bean 的方法之一。
  • 哇...这是相当旧的配置,我真的希望您使用它不是什么新东西。在没有看到您的 tx 管理器配置和 dao 实现以及您正在使用的休眠版本的解释的情况下,任何答案都只是一个猜测。您也未能解释您正在使用的数据库(以及可选的表类型)。

标签: spring


【解决方案1】:

我认为您必须提及何时应该进行回滚。 根据文档, 回滚规则的概念很重要:它们使您能够指定哪些异常(和 throwable)应该导致自动回滚。您可以在配置中以声明方式指定它,而不是在 Java 代码中。因此,尽管您仍然可以在 TransactionStatus 对象上调用 setRollbackOnly() 来回滚当前事务,但通常您可以指定 MyApplicationException 必须始终导致回滚的规则。

详情请咨询http://docs.spring.io/spring/docs/current/spring-framework-reference/html/transaction.html

【讨论】:

  • 我已经声明如果在“txProxyTemplate”bean 定义中抛出异常,事务应该回滚。 emTrcvLineDAO.create(lineVo) 必须抛出异常,因为 lineVo 数据错过了 DB 表的一些必填字段。但是,即使 emTrcvLineDAO.create(lineVo) 抛出 DataIntegrityViolationException,“emTrcvHeaderDAO.create(vo)”仍然可以成功地将数据保存到 DB。
【解决方案2】:

我终于找到了根本原因。项目中有两个重复的 Spring 配置文件都定义了事务管理规则,这使得 Spring 事务管理不起作用。删除其中一个后,它就可以工作了。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-02-09
    • 1970-01-01
    • 2013-08-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多