spring事务(Transaction )报 marked as rollback-only异常的缘由及解决方法

不少朋友在使用spring+hibernate或mybatis等框架时常常遇到报Transaction rolled back because it has been marked as rollback-only的异常,这个异常是怎么形成的java

呢,下面将给你们进行详细的分析。mysql

    这是专门写的一个形成该异常的代码:spring

@Transactional public void add(OperateLog entity)throws Exception { // TODO Auto-generated method stub operateLogDao.add(entity); } @Transactional public void save(Member member) throws Exception { memberDao.add(member); } @Transactional public void add(Member member) throws Exception { try { this.save(member); /* * 日志的title长度为10 我把值设置为add111111111111111111是为了形成异常 */ OperateLog entity = new OperateLog("add111111111111111111", "1111"); operateLogService.add(entity); } catch (Exception e) { e.printStackTrace(); // throw e; } }

执行以上代码就会报改异常,当我把
//throw e;的注释//去掉,当我执行后就不会有改异常,只会报标题title太长的异常。以下面提示:sql

Caused by: com.mysql.jdbc.MysqlDataTruncation: Data truncation: Data too long for column '_title' at row 1 at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4072) at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4006) at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2468) at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2629) at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2719) at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2155) at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2450) at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2371) at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2355) at org.apache.commons.dbcp.DelegatingPreparedStatement.executeUpdate(DelegatingPreparedStatement.java:105) at org.apache.commons.dbcp.DelegatingPreparedStatement.executeUpdate(DelegatingPreparedStatement.java:105) at org.hibernate.id.IdentityGenerator$GetGeneratedKeysDelegate.executeAndExtract(IdentityGenerator.java:94) at org.hibernate.id.insert.AbstractReturningDelegate.performInsert(AbstractReturningDelegate.java:57)

 

经过以上的问题咱们能够发现。在spring中,在事务方法中调用多个事务方法时,spring将会把这些事务合二为一。当整个方法中每一个子方法没报错时,整个方法执行完才提交事务(你们能够使用debug测试),若是某个子方法有异常,spring将该事务标志为rollback only。若是这个子方法没有将异常往上整个方法抛出或整个方法未往上抛出,那么改异常就不会触发事务进行回滚,事务就会在整个方法执行完后就会提交,这时就会形成Transaction rolled back because it has been marked as rollback-only的异常,就如上面代码中未抛throw e 同样。若是咱们往上抛了改异常,spring就会获取异常,并执行回滚。apache

相关文章
相关标签/搜索