解决Spring AOP 事务 配置 失效原因--业务类里抛出的异常不满足事务拦截器里定义的异常
来源:互联网 发布:苹果mac官方壁纸 编辑:程序博客网 时间:2024/06/06 07:17
采用AOP配置声明式事务有5种方式,下面只说关于采用TransactionInterceptor事务拦截器的方式,配置程序如下:
transactionManager:
- <bean
id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" /> -
- <bean
id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionMan ager" > -
name="dataSource" ref="dataSource" /> - </bean>
- <bean
id="transactionInterceptor" class="org.springframework.transaction.interceptor.TransactionInterceptor"> -
name="transactionManager" ref="transactionManager" /> -
name="transactionAttributes"> -
-
key="add*">PROPAGATION_REQUIRED</prop> -
key="del*">PROPAGATION_REQUIRED</prop> -
key="update*">PROPAGATION_REQUIRED</prop> -
key="query*">readOnly</prop> -
key="get*">readOnly</prop> -
key="find*">readOnly</prop> -
key="check*">PROPAGATION_REQUIRED</prop> -
key="operate*">PROPAGATION_REQUIRED</prop> -
key="batch*">PROPAGATION_REQUIRED</prop> -
key="deploy*">PROPAGATION_REQUIRED</prop> -
key="exec*">PROPAGATION_REQUIRED</prop> -
-
- </bean>
自动代理BeanNameAutoProxyCreator
- <bean
class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator " > -
name="beanNames"> -
所有以BUSImpl命名的Bean-Id都会被事务拦截--> -
-
-
name="interceptorNames"> -
-
-
- </property>
- </bean>
业务类例子:
- public
class UserManageBUSImpl implementsIBusiness{ -
UserDAO dao; -
void addUser(User throwsuser) Exception{ -
dao.save(user); -
} - }
- public
class UserDAO implementsIDAO{ -
JdbcTemplate db; -
void save(User throwsuser) Exception{ -
db.update( into );User(...) values(...)" -
new Exception( "testexception" );// 这里我们故意抛出异常作为测试 -
} - }
why?
我们首先应该知道使用事务回滚和提交,归根结底是在JDBC里完成的,这里声明事务拦截器仅是为JDK代理切入点拦截。而做事务提交和回滚是transactionManager完成的事。那么断点跟进拦截器里程序发现:
- public
Object finalinvoke( MethodInvocation throwsinvocation) Throwable { -
Work out the target class: may be <code>null</code>. -
The TransactionAttributeSour ce should be passed the target class -
as well as the method, which may be from an interface. -
Class targetClass = (invocation.getThis() != ? null);invocation.getThis().getClass() : -
-
If the transaction attribute is null, the method is non-transactional. -
TransactionAttribute txAttr = -
getTransactionAttributeS ource().getTransactionAttribute(invocation.getMethod(), targetClass); -
String joinpointIdentification = methodIdentification(invocation.getMethod()); -
-
(txAttr null== || instanceof!(getTransactionManager() CallbackPreferringPlatfo rmTransactionManager)) { -
Standard transaction demarcation with getTransaction and commit/rollback calls. -
TransactionInfo txInfo = createTransactionIfNeces sary(txAttr, joinpointIdentification); -
Object retVal = -
{ -
This is an around advice: Invoke the next interceptor in the chain. -
This will normally result in a target object being invoked. -
retVal = invocation.proceed(); -
} -
(Throwable ex) { -
target invocation exception -
<SPAN style= #000000" >completeTransactionAfterThrowing(txInfo, ex);</SPAN> -
ex; -
} -
{ -
cleanupTransactionInfo(txInfo); -
} -
commitTransactionAfterRe turning(txInfo); -
retVal; -
} - ......
completeTransactionAfter
- protected
void completeTransactionAfter Throwing(TransactionInfo txInfo, Throwable ex) { -
(txInfo null!= && txInfo.hasTransaction()) { -
(logger.isDebugEnabled()) { -
logger.debug( transaction for [" + "]txInfo.getJoinpointIdentificati on() + after exception: " + ex); -
} -
<SPAN style= #ff0000" >if(txInfo.transactionAttribute.rollbackOn(ex)) //{ 需满足这个条件</SPAN> -
{ -
<SPAN style= #ff0000" >this.transactionManager.rollback(txInfo.getTransactionStatus());// 这里才完成JDBC事务回滚</SPAN> -
} (RuntimeException ex2) { -
logger.error( exception ,overridden by rollback exception" ex); -
ex2; -
} (Error err) { -
logger.error( exception ,overridden by rollback error" ex); throwerr; } -
} - ......
-
- public
interface TransactionAttribute extendsTransactionDefinition { -
-
-
rollbackOn(Throwable ex); -
- }
- public
boolean rollbackOn(Throwable ex) { -
(logger.isDebugEnabled()) { -
logger.debug( rules to determine whether transaction should rollback on " + ex); -
} -
RollbackRuleAttribute winner = -
deepest = Integer.MAX_VALUE; -
( this.rollbackRules!= null){ -
<SPAN style= #ff0000" >//看来这里是要满足自定义回滚规则 -
(Iterator this.rollbackRules.iterator();it = it.hasNext();) { - </SPAN>
RollbackRuleAttribute rule = (RollbackRuleAttribute) it.next(); -
depth = rule.getDepth(ex); -
(depth 0>= && depth < deepest) { -
deepest = depth; winner = rule; -
} -
} -
} -
(logger.isDebugEnabled()) { -
logger.debug( rollback rule is: " + winner); -
} -
User superclass behavior (rollback on unchecked) if no rule matches. -
(winner null)== { -
logger.debug( relevant );rollback rule found: applying superclass default" -
<SPAN style= #ff0000" >returnsuper.rollbackOn(ex); // 如果没有规则,则调用父类方法验证回滚规则</SPAN> -
} -
!(winner instanceofNoRollbackRuleAttribute); }
-
- public
boolean rollbackOn(Throwable ex) { - <SPAN
style= "COLOR:#ff0000" ><SPANstyle= "COLOR:#000000" ></SPAN> (ex instanceofRuntimeException instanceof|| ex Error); //最终是这个原因</SPAN> - }
原因:
由于业务类里抛出的异常不满足事务拦截器里定义的异常(RuntimeException|Error)事务回滚规则,故事务无效;
解决方案:
1,将业务类的抛出异常改为满足拦截器里的异常规则(不推荐,因为要修改以前所有的代码)
2,(推荐方案)在事务拦截器里声明自定义回滚规则,即this.rollbackRules.iterator()中有你自己申明的异常类,这个方案仅需在spring中配置如下:
- <bean
id="transactionInterceptor" class="org.springframework.transaction.interceptor.TransactionInterceptor"> -
name="transactionManager" ref="transactionManager" /> -
name="transactionAttributes"> -
-
key="add*">PROPAGATION_REQUIRED, -Exception </prop> -
key="del*">PROPAGATION_REQUIRED, -Exception </prop> -
key="update*">PROPAGATION_REQUIRED, -Exception </prop> -
key="query*">readOnly</prop> -
key="get*">readOnly</prop> -
key="find*">readOnly</prop> -
key="check*">PROPAGATION_REQUIRED, -Exception </prop> -
key="operate*">PROPAGATION_REQUIRED, -Exception </prop> -
key="batch*">PROPAGATION_REQUIRED, -Exception </prop> -
key="deploy*">PROPAGATION_REQUIRED, -Exception </prop> -
key="exec*">PROPAGATION_REQUIRED, -Exception </prop> -
-
- </bean>
转载地址:http://blog.sina.com.cn/s/blog_56fd58ab0100gjhv.html
- 解决Spring AOP 事务 配置 失效原因--业务类里抛出的异常不满足事务拦截器里定义的异常
- 解决Spring AOP 事务 配置 失效原因
- 抛出自定义异常,spring AOP事务不回滚的解决方案
- 抛出自定义异常,spring AOP事务不回滚的解决方案
- spring 里的事务配置
- spring AOP 拦截器方式配置事务失效
- 通过spring的aop统一拦截Exception抛出自定义异常
- Spring事务失效的原因
- Spring事务失效的原因
- spring 事务失效的原因
- Spring事务失效的原因
- spring事务控制的方法中抛出异常不回滚
- spring AOP的异常拦截
- spring AOP的异常拦截
- spring AOP的异常拦截
- spring AOP的异常拦截
- spring AOP的异常拦截
- spring 声明式事务配置,抛出runtimeException异常不回滚
- PopupWindow和AlertDialog区别
- 第十四周项目2-二叉树排序树中查找的路径
- HTML5清除默认格式代码
- hashset实现原理
- 十一周项目一 验证算法二查数算法的验证
- 解决Spring AOP 事务 配置 失效原因--业务类里抛出的异常不满足事务拦截器里定义的异常
- 第5章 Spring Boot基础
- 打造扛得住的MYSQL数据库架构
- Android M动态申请获取权限android.permission.READ_PHONE_STATE
- Jquery获取标签及对标签的相关操作
- 高仿Demo获取该App图片
- mysql启动失败Starting MySQL.The server quit without updating PID file ([失败]ysqllnmp.pid)
- protobuf 自动生成c# .cs文件 -protogen用法
- QT4.7开发环境搭建主要步骤,全志A33 + win7桌面版