我有一个场景,其中使用了两个不同的数据源。
DataSource1服务类(支持事务)调用DataSource2服务类方法(支持事务,但带有datasource2)
代码如下所示。我的需求是如何在一个单独的事务中运行persistOneByOne(),当我们调用这个hierarchy.If异常时,不要持久化那个记录,但是因为它在for循环中继续处理其他记录。我如何实现此行为。
// Service class 2使用数据源-1,它是由aop启用的事务
public class DataSource1ServiceClass1{
DataSource2OtherServiceClass service2;
public void processData(){
service2.prepareAndPeristData();
}
}// Service class 2使用另一个名为datasource-2的数据源,它也是由aop启用的事务
public class DataSource2OtherServiceClass{
public void prepareAndPeristData(){
try{
for(int i=0;i<10;i++)
{
// pre processing before persisting a single record
persistOneByOne();
}
}catch (Exception e){
log.error("Error occurred.. so didn't persist record as expected"};
}
public void persistOneByOne()
{
dao.persist();
}
}配置xml文件:
<bean id="txManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<tx:advice id="txAdvice" transaction-manager="txManager">
<tx:attributes>
<tx:method name="*" />
</tx:attributes>
</tx:advice>
<aop:config>
<aop:pointcut id="allServices"
expression="execution(* .service.impl.*.*(..))" />
<aop:advisor advice-ref="txAdvice" pointcut-ref="allServices" />
</aop:config>
<bean id="txManager2"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="otherDataSource" />
</bean>
<tx:advice id="txAdvice2" transaction-manager="txManager2">
<tx:attributes>
<tx:method name="*" />
</tx:attributes>
</tx:advice>
<aop:config>
<aop:pointcut id="allOtherServices"
expression="execution(* .service2.impl.*.*(..))" />
<aop:advisor advice-ref="txAdvice2" pointcut-ref="allOtherServices" />
</aop:config>如何实现在其自己事务中运行persistOneByOne()?对于单行发生.if异常回滚。
发布于 2016-07-02 00:12:58
我认为您的场景适合基于保存点的数据库交互。Spring通过NESTED传播来支持它。
如果将嵌套传播建议应用于代码中的persistOneByOne()方法,那么每次执行该方法时,它都会创建一个保存点,如果发生异常,它将回滚到最后一个保存点。然后继续下一步。
从技术上讲,您也可以通过将REQUIRES_NEW传播建议应用于您的方法来做到这一点,但是它会在每次使用called.It时打开一个新事务,这被认为是一种糟糕的做法,因为它会在大量事务的情况下颠覆您的数据库。
您可以查看以下内容以了解更多详细信息:http://www.marcobehler.com/make-it-so-java-db-connections-and-transactions-html/spring-transactional-propagation-propagation-nested.html
此外,您还可以从txManager2的配置中删除事务通知,然后使用@Transactional注释来注释方法/类,而不是使用transactionManager注释。文档:http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/transaction/annotation/Transactional.html
您需要在配置中添加以下内容:
<tx:annotation-driven proxy-target-class="true"/>这样,你的类看起来就像这样:
public class DataSource2OtherServiceClass{
@Transactional(rollbackFor = {Exception.class}, propagation=PROPAGATION.REQUIRES_NEW, transactionManager="txManager2")
public void prepareAndPeristData(){
try{
for(int i=0;i<10;i++)
{
// pre processing before persisting a single record
persistOneByOne();
}
}catch (Exception e){
log.error("Error occurred.. so didn't persist record as expected"};
}
@Transactional(rollbackFor = {Exception.class}, propagation=PROPAGATION.NESTED, transactionManager="txManager2")
public void persistOneByOne()
{
dao.persist();
}
}https://stackoverflow.com/questions/37988583
复制相似问题