您的位置:首页技术文章
文章详情页

java - Spring事务配置在service层,传播规则为required,方法中究竟应该是调用service还是多个dao比较好?

【字号: 日期:2023-12-21 11:53:56浏览:17作者:猪猪

问题描述

Spring中事务配置如下:

<tx:advice 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 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容器会自动截获异常,进行事务回滚处理。

问题解答

回答1:

如果你想更多了解Spring事务机制可以看我的这几篇文章:

Spring Transaction详解 - Transaction Isolation

Spring Transaction详解 - Transaction Propagation模式

Spring Transaction详解 - 手动回滚事务

Spring Transaction详解 - 异常发生时的事务回滚机制

回答2:

其实这种事情就是根据需要了,事务是会自动合并的,但作为设计考虑,尽量调用 dao 这样能够使不同的 service 得以解偶。

回答3:

一般我们在Service的方法上会进行事务的定义,特别是如果有控制传播行为的场景,那放入dao就和放入service不同了。因为dao肯定都是在一个大事务下了,service就比较复杂了。

标签: java