java 事务不能回滚问题
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java 事务不能回滚问题相关的知识,希望对你有一定的参考价值。
public static void test()
String sql = "update t_test set name = 5 where id = 5";
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
try
conn = DBUtil.getConn();
conn.setAutoCommit(false);
ps = conn.prepareStatement(sql);
ps.executeUpdate();
conn.commit();
if(true)//故意出现Exception
throw new SQLException("wrong");
catch (SQLException e)
try
conn.rollback();//出现了异常,不会回滚!
catch (SQLException e1)
e1.printStackTrace();
throw new DaoException(e.getMessage(),e);
finally
DBUtil.close(rs, ps, conn);
为何事务不会回滚?回滚有什么要求?是不是回滚一定要放在catch的Exception里?
我用的是mysql,表类型也是InnoDB的,
我自己猜想啊 这个try捕获的是执行异常
就是发生在数据库中的异常
而你自己抛出的这个异常时另外一个异常
你试一下把new给去掉
你这个代码如果出现异常一定是会回滚的 参考技术C 你都提交了,然后才出现错误,当然不回滚了。你将异常放到commit前面。 参考技术D 是的。
Service中事务不能回滚的解决方式(转)
1、在service方法里面如果对异常进行了捕获的话,该事务是不会进行回滚的
默认spring事务只在发生未被捕获的 runtimeexcetpion时才回滚。
spring aop 异常捕获原理:被拦截的方法需显式抛出异常,并不能经任何处理,这样aop代理才能捕获到方法的异常,才能进行回滚,默认情况下aop只捕获runtimeexception的异常,但可以通过配置来捕获特定的异常并回滚,换句话说在service的方法中不使用try catch 或者在catch中最后加上throw new runtimeexcetpion(),这样程序异常时才能被aop捕获进而回滚
解决方案:
方案1.例如service层处理事务,那么service中的方法中不做异常捕获,或者在catch语句中最后增加throw new RuntimeException()语句,以便让aop捕获异常再去回滚,并且在controller层要继续捕获这个异常并处理
方案2.在service层方法的catch语句中增加:TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();语句,手动回滚,这样上层就无需去处理异常(现在项目的做法)
在service中try。。。catch,在catch块中抛出runtimeException无法实现回滚,不知道为什么。
现在的解决时方案2.或者controller回滚。
以上是关于java 事务不能回滚问题的主要内容,如果未能解决你的问题,请参考以下文章