Spring 事务不回滚的问题关键是:不能对该异常用try...catch处理,否则不会回滚事务!
@Service("systemConfigService") public class SystemConfigServiceImpl extends AbstractGenericService<SystemConfig> implements SystemConfigService { @Resource(name="systemConfigDAO") private SystemConfigDAO systemConfigDAO; @Override public void deleteByIds(String id) { if(id != null){ String[] ids = id.split(","); try { SystemConfig systemConfig = systemConfigDAO.get(2); systemConfig.setValue("测试值"); systemConfigDAO.update(systemConfig); // 执行如下操作,数据库将报唯一索引重复问题 // Caused by: java.sql.BatchUpdateException: Duplicate entry 'PORTAL.CITYCODE' for key 'name' SystemConfig systemConfig2 = systemConfigDAO.get(2); systemConfig2.setName("PORTAL.CITYCODE"); systemConfigDAO.update(systemConfig2); } catch (Exception e) { log.error(e); // 如果注释掉throw new RuntimeException,那么事务将不能回滚,因为spring捕捉不到Exception // 解决办法,去掉try catch,或者在cache中抛出异常以便spring捕获 throw new RuntimeException("运行时出错!"); } } } }
<aop:config proxy-target-class="true" /> <!--cglib事物--> <tx:annotation-driven proxy-target-class="true" transaction-manager="transactionManager" /> @Transactional 必须使用tx:annotation-driven 开启注解事务支持
Connection conn ; try{ conn = DriverManager.getConnection();//①获取数据连接 conn.setAutoCommit(false); //②关闭自动提交的机制 conn.setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE); //③设置事务隔离级别 Statement stmt = conn.createStatement(); int rows = stmt.executeUpdate( "INSERT INTO t_topic VALUES(1,’tom’) " ); rows = stmt.executeUpdate( "UPDATE t_user set topic_nums = topic_nums +1 "+ "WHERE user_id = 1"); conn.commit();//④提交事务 }catch(Exception e){ … conn.rollback();//⑤回滚事务 }finally{ … }
Statement stmt = conn.createStatement(); int rows = stmt.executeUpdate( "INSERT INTO t_topic VALUES(1,’tom’)"); Savepoint svpt = conn.setSavepoint("savePoint1");//①设置一个保存点 rows = stmt.executeUpdate( "UPDATE t_user set topic_nums = topic_nums +1 "+ "WHERE user_id = 1"); … //②回滚到①处的savePoint1,①之前的SQL操作,在整个事务提交后依然提交, //但①到②之间的SQL操作被撤销了 conn.rollback(svpt); … conn.commit();//③提交事务