1测试controller
@Controller
public class DemoController2 {
@Autowired
private DemoService demoService;
/**
*
* @param response
* @param resquest
*/
@RequestMapping(value = "/demoController2/selectList.do")
public void selectList(HttpServletResponse response,HttpServletRequest resquest){
Customer customer=new Customer();
customer.setApplicationNO("D00021807040005");
customer.setId_card("11111");
System.out.println("更新数据开始");
demoService.update(customer);
System.out.println("更新数据结束:"+customer.getId_card());
}
}
2回滚测试service
情况1
@Overridepublic void update(Customer customer) {// TODO Auto-generated method stubtry {customerDao.update(customer);int i=7/0;} catch (RuntimeException e) {//抛出RuntimeException
e.printStackTrace();}}
情况2
@Override
public void update(Customer customer) {
// TODO Auto-generated method stub
try {
customerDao.update(customer);
int i=7/0;
} catch (Exception e) {//抛出Exception
e.printStackTrace();
}
}
情况1和情况2都抛出异常,但是事务没有回滚
结果
2018-07-16 09:29:10,916 [http-bio-8080-exec-3] DEBUG [com.xx.core.dao.pushBusiness.CustomerDao.update] - ==> Preparing: update ap_customer SET id_card=? where applicationNO=?
2018-07-16 09:29:10,933 [http-bio-8080-exec-3] DEBUG [com.xx.core.dao.pushBusiness.CustomerDao.update] - ==> Parameters: 11111(String), D00021807040005(String)
2018-07-16 09:29:10,934 [http-bio-8080-exec-3] DEBUG [com.xx.core.dao.pushBusiness.CustomerDao.update] - <== Updates: 1
2018-07-16 09:29:10,934 [http-bio-8080-exec-3] DEBUG [org.mybatis.spring.SqlSessionUtils] - Releasing transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@7f7a33c1]
java.lang.ArithmeticException: / by zero
情况3
tp-bio-8080-exec-3] DEBUG [org.mybatis.spring.transaction.SpringManagedTransaction] - JDBC Connection [jdbc:mysql://127.0.0.1:3306/test_zhou?characterEncoding=UTF-8, UserName=root@localhost, MySQL-AB JDBC Driver] will be managed by Spring
2018-07-16 09:38:09,213 [http-bio-8080-exec-3] DEBUG [com.xx.core.dao.pushBusiness.CustomerDao.update] - ==> Preparing: update ap_customer SET id_card=? where applicationNO=?
2018-07-16 09:38:09,230 [http-bio-8080-exec-3] DEBUG [com.xx.core.dao.pushBusiness.CustomerDao.update] - ==> Parameters: 11111(String), D00021807040005(String)
2018-07-16 09:38:09,231 [http-bio-8080-exec-3] DEBUG [com.xx.core.dao.pushBusiness.CustomerDao.update] - <== Updates: 1
2018-07-16 09:38:09,231 [http-bio-8080-exec-3] DEBUG [org.mybatis.spring.SqlSessionUtils] - Releasing transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@51fdadfa]
2018-07-16 09:38:12,955 [http-bio-8080-exec-3] DEBUG [org.mybatis.spring.SqlSessionUtils] - Transaction synchronization deregistering SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@51fdadfa]
2018-07-16 09:38:12,956 [http-bio-8080-exec-3] DEBUG [org.mybatis.spring.SqlSessionUtils] - Transaction synchronization closing SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@51fdadfa]
2018-07-16 09:38:12,956 [http-bio-8080-exec-3] DEBUG [org.springframework.jdbc.datasource.DataSourceTransactionManager] - Initiating transaction rollback
2018-07-16 09:38:12,957 [http-bio-8080-exec-3] DEBUG [org.springframework.jdbc.datasource.DataSourceTransactionManager] - Rolling back JDBC transaction on Connection [jdbc:mysql://127.0.0.1:3306/test_zhou?characterEncoding=UTF-8, UserName=root@localhost, MySQL-AB JDBC Driver]
结果:抛出异常,且事务回滚
2018-07-16 09:42:29,245 [http-bio-8080-exec-8] DEBUG [com.xx.core.dao.pushBusiness.CustomerDao.update] - ==> Preparing: update ap_customer SET id_card=? where applicationNO=?
2018-07-16 09:42:29,245 [http-bio-8080-exec-8] DEBUG [com.xx.core.dao.pushBusiness.CustomerDao.update] - ==> Parameters: 11111(String), D00021807040005(String)
2018-07-16 09:42:29,246 [http-bio-8080-exec-8] DEBUG [com.xx.core.dao.pushBusiness.CustomerDao.update] - <== Updates: 1
2018-07-16 09:42:29,246 [http-bio-8080-exec-8] DEBUG [org.mybatis.spring.SqlSessionUtils] - Releasing transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@7714bd9]
2018-07-16 09:42:29,246 [http-bio-8080-exec-8] DEBUG [org.springframework.jdbc.datasource.DataSourceTransactionManager] - Transactional code has requested rollback
2018-07-16 09:42:29,246 [http-bio-8080-exec-8] DEBUG [org.mybatis.spring.SqlSessionUtils] - Transaction synchronization deregistering SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@7714bd9]
2018-07-16 09:42:29,246 [http-bio-8080-exec-8] DEBUG [org.mybatis.spring.SqlSessionUtils] - Transaction synchronization closing SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@7714bd9]
2018-07-16 09:42:29,246 [http-bio-8080-exec-8] DEBUG [org.springframework.jdbc.datasource.DataSourceTransactionManager] - Initiating transaction rollback
2018-07-16 09:42:29,246 [http-bio-8080-exec-8] DEBUG [org.springframework.jdbc.datasource.DataSourceTransactionManager] - Rolling back JDBC transaction on Connection [jdbc:mysql://127.0.0.1:3306/test_zhou?characterEncoding=UTF-8, UserName=root@localhost, MySQL-AB JDBC Driver]
2018-07-16 09:42:29,250 [http-bio-8080-exec-8] DEBUG [org.springframework.jdbc.datasource.DataSourceTransactionManager] -
原因
默认spring事务只在发生未被捕获的 runtimeExcetpion时才回滚。
1spring aop 异常捕获原理:被拦截的方法需显式抛出异常,并不能经任何处理,这样aop代理才能捕获到方法的异常,才能进行回滚,默认情况下aop只捕获runtimeException的异常。
2可以通过 配置来捕获特定的异常并回滚
1在service的方法中不使用try catch
2在catch中最后加上throw new runtimeexcetpion(),这样程序异常时才能被aop捕获进而回滚
解决方案:
方案1.例如service层处理事务,那么service中的方法中不做异常捕获,或者在catch语句中最后增加throw new RuntimeException()语句,以便让aop捕获异常再去回滚,并且在service上层(webservice客户端,view层action)要继续捕获这个异常并处理
方案2.在service层方法的catch语句中增加:TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();语句,手动回滚,这样上层就无需去处理异常(现在项目的做法)