Spring事务回滚
配置事物:
@Configuration
/**强制使用cglib代理时就把proxy-target-class设为true.*/
@EnableTransactionManagement(proxyTargetClass=true)
public class DataBaseConfiguration implements TransactionManagementConfigurer{ @Bean(name="testpackageTransactionManager")
@Qualifier("testpackageTransactionManager")
public PlatformTransactionManager testpackageTransactionManager() {
return new DataSourceTransactionManager(testpackageDataSource());
}
}
事物回滚错误示例:
示例一:
@Transactional(value = "testpackageTransactionManager", rollbackFor = RuntimeException.class)
@RequestMapping("/rollback")
public void rollback() {
try {
TestEntity test = new TestEntity();
test.setMark("======rollback tran test========");
testMapper.insertSelective(test);
throw new Exception("出错了========!");
} catch (Exception ex) {
System.out.println("出错了回滚事物");
}
}
被try catch处理的事物不会回滚。
下面的方法会成功回滚:
示例二:
手动回滚:
@Transactional(value = "testpackageTransactionManager", rollbackFor = RuntimeException.class)
@RequestMapping("/rollback")
public void rollback() {
try {
TestEntity test = new TestEntity();
test.setMark("======rollback tran test========");
testMapper.insertSelective(test);
throw new Exception("出错了========!");
} catch (Exception ex) {
System.out.println("出错了回滚事物");
//手动回滚
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
}
}
示例三:
指定事物回滚rollbackFor = Exception.class ,抛出Exception、RuntimeException、DiyException(自定义继承自Exception的异常)异常都可以成功回滚
@Transactional(value = "testpackageTransactionManager", rollbackFor = Exception.class)
@RequestMapping("/testTran3")
public void testTran3() throws Exception {
try {
TestEntity test = new TestEntity();
test.setMark("======rollback tran test 2========");
testMapper.insertSelective(test); throw new Exception("出错了回滚事物==!");
} catch (Exception ex) {
System.out.println("出错了回滚事物");
throw new Exception("出错了回滚事物");
//throw new RuntimeException("出错了回滚事物");
//throw new DiyException(); 继承自Exception的自定义异常
} }
示例四:
指定事物回滚rollbackFor =RuntimeException.class ,只有抛出RuntimeException类型的异常,才会回滚事物
/**事物回滚成功*/
@Transactional(value = "testpackageTransactionManager", rollbackFor = RuntimeException.class)
@RequestMapping("/testTran4")
public void testTran4() throws Exception {
try {
TestEntity test = new TestEntity();
test.setMark("======rollback tran test 2========");
testMapper.insertSelective(test);
throw new Exception("出错了回滚事物==!");
} catch (Exception ex) {
System.out.println("出错了回滚事物");
throw new RuntimeException("出错了回滚事物");
}
}
为什么【示例一】不会滚呢??是对spring的事务机制就不明白。!!
默认spring 事务只在发生未被捕获的 RuntimeExcetpion时才回滚。
Spring Aop 异常捕获原理:被拦截的方法需显式抛出异常,并不能经任何处理,这样Aop代理才能捕获到方法的异常,才能进行回滚,默认情况下Aop只捕获RuntimeExcetpion的异常,但可以通过 配置来捕获特定的异常并回滚换句话说在service的方法中不使用try catch 或者在catch中最后加上throw new RuntimeExcetpion(),这样程序异常时才能被Aop捕获进而回滚
解决方案:
方案1.例如service层处理事务,那么service中的方法中不做异常捕获,或者在catch语句中最后增加throw new RuntimeExcetpion()语句,以便让Aop捕获异常再去回滚,并且在service上层(webservice客户端,view层action)要继续捕获这个异常并处理
方案2.在service层方法的catch语句中增加:TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();语句,手动回滚,这样上层就无需去处理异常(现在项目的做法)。
最新文章
- 关于JavaScript中的delete操作
- pointers on c (day 1,chapter3)
- KVM 虚拟化 初体验
- 网络与RPC
- JQuery上传插件uploadify整理(Options)
- C++虚函数的缺陷
- vertical-align:middle图片或者按钮垂直居中
- C++类型引用浅析
- Reason: Server is in single user mode. Only one administrator can connect at this time
- CocoaPods不更新spec仓库进行install/update
- 使用ionic与cordova(phonegap)进行轻量级app开发前的环境配置与打包安卓apk过程记录
- MySQL常用的查询命令
- OO第一单元总结与心得体会
- haproxy 配置文件分析
- DS博客作业03——栈和队列
- 基于maven来Spring MVC的环境搭建遇到“坑”
- [PHP] php + phpstudy + phpstrom + xdebug + postman开启调试
- Sql 按照指定天数时间段查询
- 使用别名访问MSSQL Express
- AWS CSAA -- 04 AWS Object Storage and CDN - S3 Glacier and CloudFront(三)
热门文章
- 当苹果因为UIDevice、udid、uniqueIdentifier而把我们的应用拒之门外invalid binary的时候,呕心沥血解决方法啊
- WEB安全番外第五篇--关于使用通配符进行OS命令注入绕WAF
- mysql5.6的二进制包安装
- Spring的Bean的生命周期以及Bean的后置处理器
- initialize myObject by calling a function that returns an object literal
- (转)聊聊Servlet、Struts1、Struts2以及SpringMvc中的线程安全
- 时间序列模式——ARIMA模型
- python 将日期戳(五位数时间)转换为标准时间
- Python并行编程(六):线程同步之条件
- javaScript 调用构造函数 Array() 时没有使用参数, length总是0