Spring中事务配置如下:
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="delete*" propagation="REQUIRED" read-only="false"
rollback-for="java.lang.Exception"/>
<tx:method name="insert*" propagation="REQUIRED" read-only="false"
rollback-for="Exception" />
<tx:method name="update*" propagation="REQUIRED" read-only="false"
rollback-for="java.lang.Exception" />
<tx:method name="save*" propagation="REQUIRED" read-only="false"
rollback-for="Exception" />
<tx:method name="*" propagation="REQUIRED" read-only="true"/>
<:attributes>
<:advice>
现在ServiceA
中有一个方法methodA
,那么在ServiceA
中应该注入ServiceB,ServiceC
呢,还是DaoB,DaoC
,然后在methodA
中去保存B,C
,保证B,C
同时保存成功,或同时失败!
答:
既可以单独注入service,也可以单独注入dao,关键是,spring容器的事务管理默认只截获未检查异常RuntimeException。上边配置的rollback-for="java.lang.Exception"其实不用配置
。配置如下
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="delete*" propagation="REQUIRED" read-only="false" />
<tx:method name="insert*" propagation="REQUIRED" read-only="false" />
<tx:method name="update*" propagation="REQUIRED" read-only="false" />
<tx:method name="save*" propagation="REQUIRED" read-only="false" />
<tx:method name="*" propagation="REQUIRED" read-only="true"/>
<:attributes>
<:advice>
解决方案是:
如果代码中使用了try...catch...捕获了检查型异常,意味着程序员自己必须要解决异常,必须知道如何解决异常。通常的做法是:将检查型的异常在catch块中重新抛出为Runtime Exception
,这样Spring容器就会截获该异常,进行事务回滚处理 。如下
try {
.....
}catch( CheckedException e ) {
logger.error(e);
throw new RuntimeException(e);
}
注意,不使用try...catch...,而在方法签名后向外抛出检查型异常的行为不可取,事务也不会回滚。
如果代码中没有使用try抛出了未检查异常,则Spring容器会自动截获异常,进行事务回滚处理。
Si vous souhaitez en savoir plus sur le mécanisme de transaction Spring, vous pouvez lire ces articles :
Explication détaillée de Spring Transaction - Isolation des transactions
Explication détaillée de Spring Transaction - Mode de propagation des transactions
Explication détaillée de Spring Transaction - Annulation manuelle de la transaction
Explication détaillée de Spring Transaction - mécanisme d'annulation de transaction lorsqu'une exception se produit
En fait, ce genre de chose se fait en fonction des besoins, et les transactions seront automatiquement fusionnées. Cependant, pour des raisons de conception, essayez d'appeler dao afin que les différents services puissent être découplés.
Généralement, nous définissons les transactions dans la méthode
Service
, surtout s'il existe un scénario pour contrôler le comportement de propagation, alors mettredao
est différent de mettreservice
. Parce quedao
tout doit se dérouler sous un seul grand événement,service
est plus compliqué.