2016-11-06 197 views
1

我介绍了一个问题“春季交易失败回滚”。我有一个服务类,它调用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> 
+0

emTrcvHeaderDAO.create(VO)应rollack为emTrcvLineDAO.create(lineVo)失败并引发org.springframework.dao.DataIntegrityViolationException ,但实际上emTrcvHeaderDAO.create(VO)不会回退和VO数据仍然可以插入D B。为什么? – runboy2000

+0

saveEmTrcvHeader()是emTrcvHeaderService服务bean的一种方法。 – runboy2000

+0

哇...这是非常古老的配置,我真的希望这不是你正在使用它的新东西。没有看到你的tx管理器配置和dao实现以及你正在使用哪个hibernate版本的解释,任何答案都只是一个猜测。您也无法解释哪个数据库(以及您正在使用的表类型)。 –

回答

0

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

请了解更多详情

+0

我已经声明事务应该回滚,如果异常抛出“txProxyTemplate”bean定义。 emTrcvLineDAO.create(lineVo)必须抛出异常,因为lineVo数据会丢失数据库表的某些必填字段。但是,“emTrcvHeaderDAO.create(vo)”仍然可以将数据成功保存到数据库,甚至emTrcvLineDAO.create(lineVo)也会抛出DataIntegrityViolationException。 – runboy2000