很多朋友在使用spring+hibernate或mybatis等框架時經常遇到報Transaction rolled back because it has been?marked as rollback-only的異常,這個異常是怎么造成的
呢,下面將給大家進行詳細的分析。
這是專門寫的一個造成該異常的代碼:
~~~
@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太長的異常。如下面提示:
~~~
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](http://blog.csdn.net/mr_smile2014)的異常,就如上面代碼中未拋throw e 一樣。如果我們往上拋了改異常,spring就會獲取異常,并執行回滾。
- 前言
- spring事務(Transaction )報 marked as rollback-only異常的原因及解決方法
- 自己整理的編碼規范總結。(個人覺得很受用)
- spring事務常見問題、異常分析和解決方法
- 剖析OutOfMemoryError: PermGen space產生原因及解決方法
- 剖析java.lang.OutOfMemoryError: Java heap space產生原因及解決方法
- java中不同的ORM框架實現對數據庫批量插入數據庫的方式與技巧
- 解決java讀取大文件內存溢出問題、如何在不重復讀取與不耗盡內存的情況下處理大文件
- 不得不看的Java代碼性能優化總結
- 實現使用3des在頁面js加密,后臺java解密
- Java日志記錄的5條規則