-
spring 事务疑惑3
情况是这样的,分别A,B2个服务,A服务调用B服务的代码。我B服务的b方法抛出了一个业务异常,我在A服务捕获了,但是事务还是回滚了? 这是为什么?
- public void testA() throws BussinessException {
- try {
- bService.testB();
- } catch (BussinessException e) {
- System.out.println(e.getErrorCode());
- }
- pictureService.addPicture("", "", "a.jpg", "", new File("d:/1.jpg"));
- }
spring事务配置:
- <bean id="txManager"
- class="org.springframework.orm.hibernate3.HibernateTransactionManager">
- <property name="sessionFactory" ref="sessionFactory" />
- </bean>
- <tx:advice id="txAdvice" transaction-manager="txManager">
- <tx:attributes>
- <tx:method name="*" rollback-for="com.soft.core.BussinessException" />
- </tx:attributes>
- </tx:advice>
- <aop:config>
- <aop:pointcut id="all" expression="execution(* com.soft.*.*.*ServiceImpl.*(..))"/>
- <aop:advisor advice-ref="txAdvice" pointcut-ref="all"/>
- </aop:config>
问题补充:kejinyou 写道事务的特性:
1、原子性
2、一致性
3、隔离性
4、持久性
你service层所有的方法都注册了事务,如果某个方法发生异常,自然会回滚的。
我捕获了这个异常了,按理不应该回滚啊2011年12月15日 14:29
3个答案按时间排序按投票排序
-
你的b serivce的方法transaction配置propagation属性使用的默认值吧。这样a和b公用一个tranasction。transactionmanager中有这样一个参数globalRollbackOnParticipationFailure,即部分失败整个事务rollback。
spring对于这样的事务管理是当a调用b,b失败了会对事务做一个回滚标志。在a事务提交时再做判断
- f (!shouldCommitOnGlobalRollbackOnly() && defStatus.isGlobalRollbackOnly()) {
- if (defStatus.isDebug()) {
- logger.debug("Global transaction is marked as rollback-only but transactional code requested commit");
- }
- processRollback(defStatus);
- // Throw UnexpectedRollbackException only at outermost transaction boundary
- // or if explicitly asked to.
- if (status.isNewTransaction() || isFailEarlyOnGlobalRollbackOnly()) {
- throw new UnexpectedRollbackException(
- "Transaction rolled back because it has been marked as rollback-only");
- }
- return;
- }
如想要b失败了不影响a的话,可以将b的propagation=Propagation.REQUIRES_NEW,让自己在一个事务中
2011年12月28日 14:51
-
从lz说的情况,b方法和a方法是在一个事务里执行的(而不是嵌套事务),
因为是b方法抛出业务异常(且未捕获处理),
因此spring事务拦截器,在拦截b方法执行时,是会设置当前事务(二者执行的事务)为回滚状态,所以spring事务拦截器在处理a方法时,发现当前事务已经被置为“回滚”,这样的情况下,正常作为是应该将当前事务回滚的。
如果b是执行在一个独立的事务中(于本例,就是嵌套事务),且抛出businessexception(或者子类型异常),是不会影响外层事务的。2011年12月15日 16:58
-
事务的特性:
1、原子性
2、一致性
3、隔离性
4、持久性
你service层所有的方法都注册了事务,如果某个方法发生异常,自然会回滚的。 -