Spring宣告式事務報錯"Transaction rolled back because it has been marked as rollback-only"分析...
在HGXP專案的資質校驗功能中出現了這樣一個報錯資訊:"Srping Transaction rolled back because it has been marked as rollback-only“,很明顯是事務管理中出的問題,再檢視資質校驗的程式碼找到出錯的位置之後,覺得事情可能並不是這麼簡單,於是在網上搜集了一下相關的問題,發現出現這個問題的朋友並不在少數,這裡簡單分析、總結一下這個報錯的原因和解決方法。
由於HGXP專案中資質校驗的邏輯程式碼太長(一個校驗方法足足有 1000多行),這裡就借用網友寫的測試方法:
首先定義一個宣告瞭事務的類:
@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
,當它沒有被註釋掉的時候,該方法不會報rollback的錯,只會報標題過長的錯,如下:
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就會獲取異常,並執行回滾。
相關文章
- Transaction rolled back because it has been marked as rollback-only
- Spring-宣告式事務Spring
- 三 Spring 宣告式事務Spring
- Spring宣告式事務控制Spring
- 全面分析 Spring 的程式設計式事務管理及宣告式事務管理Spring程式設計
- Spring宣告式事務@Transactional使用Spring
- spring宣告式事務管理配置Spring
- Spring的事務管理(二)宣告式事務管理Spring
- Spring @Transactional 宣告式事務揭祕Spring
- 深刻理解Spring宣告式事務Spring
- Spring宣告式事務管理出錯示例與解決之道Spring
- 五(二)、spring 宣告式事務xml配置SpringXML
- 分散式事務 TCC-Transaction 原始碼分析 —— 事務恢復分散式原始碼
- 分散式事務 TCC-Transaction 原始碼分析 —— 除錯環境搭建分散式原始碼除錯
- Spring宣告式事務控制原理之宣告式事務的重要元件在AOP中的應用Spring元件
- Spring的四種宣告式事務的配置-Hibernate事務Spring
- Spring宣告式事務純xml模式回顧SpringXML模式
- JavaEE(12)Spring整合Mybaits、宣告式事務JavaSpringAI
- Spring boot +mybatis 實現宣告式事務管理Spring BootMyBatis
- spring宣告式事務無法關閉sessionSpringSession
- Spring筆記(4) - Spring的程式設計式事務和宣告式事務詳解Spring筆記程式設計
- Springboot資料庫事務處理——Spring宣告式事務Spring Boot資料庫
- Spring宣告式事務的兩種實現方式Spring
- 筆記53-Spring jdbcTemplate&宣告式事務筆記SpringJDBC
- 分散式事務 TCC-Transaction 原始碼分析 —— Dubbo 支援分散式原始碼
- Spring中的AOP,以及宣告式事務 @Transactional無法攔截事務Spring
- Spring MVC + Mybatis + Spring Aop宣告式事務管理沒有作用SpringMVCMyBatis
- Spring事務的介紹,以及基於註解@Transactional的宣告式事務Spring
- Spring宣告式事務注意點,以及不生效情況Spring
- Spring程式設計式和宣告式事務例項講解Spring程式設計
- 分散式事務 TCC-Transaction 原始碼分析 —— 運維平臺分散式原始碼運維
- indexedDB transaction 事務Index
- SpringMVC、MyBatis 宣告式事務管理SpringMVCMyBatis
- 宣告式事務能否和程式設計式事務巢狀使用?程式設計巢狀
- 分散式事務ORA-24784報錯分散式
- springcloudconfig訪問gitee報錯:Authentication is required but no CredentialsProvider has been registeredSpringGCCloudGiteeUIIDE
- BUG記錄-Sharing is only supported for boot loader classes because bootstrap classpath has been appendebootAPP
- Error: php@8.0 has been disabled because it is a versioned formula! It was disabled on 2023-11-29.ErrorPHPORM