![](/img/trans.png)
[英]Wrapping a Monolith JSF/Spring application with Spring Boot
[英]wrapping multiple calls in a transaction in spring boot application?
我正在使用jdbctemplate在我的spring應用程序中對db執行查詢。
這是使用@Transactional注釋的方法
@Transactional
public boolean doSomething(){
try {
jdbcTemplate.update(sql1); //1
jdbcTemplate.update(sql2); //2
jdbcTemplate.update(sql3); //3
return true;
} catch (Exception ex){
return false;
}
}
我的問題是,如果1和2成功而3失敗,1和2上的交易是否會回滾? 我該怎么測試呢?
另外有一個布爾值作為返回值是一個表明交易狀態的好習慣嗎?
沒有! 如果你捕獲異常,你的sql將不會回滾!
這不會觸發回滾。 你需要刪除try-catch。 但是,如果拋出運行時異常,這些將按預期回滾。 請參考以下文檔。
@Transactional設置
您會看到幾行內容,任何RuntimeException都會觸發回滾。 因此,如果您捕獲異常,它將不會觸發回滾,它將在您返回false時簡單地結束事務。 另外請注意,如果拋出一個已檢查的異常,它將不會回滾,所以不要試圖通過拋出異常來解決這個問題,以便做你要對該布爾返回值做的任何事情。
我自己沒有嘗試過,但是如果你在@Transactional上設置rollbackFor屬性或者在這個方法的外部捕獲RuntimeException,你似乎可以回滾檢查異常? 或拋出自己的運行時異常? 我把它留給你。
如上所述,這也適用於存儲庫,您可以在此處查看示例
Spring Data(Repositories)事務
http://docs.spring.io/spring-data/jpa/docs/current/reference/html/#transactions
如果3失敗,則1和2將回滾。 這是交易的核心點(工作單位)。
基於@ Zergleb答案的重要更正 :僅當您拋出異常時。 在你的代碼中,你正在咀嚼異常,因此1和2將持續存在,因為事務沒有“看到”異常它不知道出現了什么問題。
要測試,在sql3
放入一些無效的sql,看看會發生什么。
我通常不會返回一個布爾值來表示成功。 成功是方法的成功完成,你應該讓異常冒泡或將異常包裝在更合適的東西中,並拋出它,如果你的場景表明這樣。
例如:
@Transactional
public void doSomething(){
try {
jdbcTemplate.update(sql1); //1
jdbcTemplate.update(sql2); //2
jdbcTemplate.update(sql3); //3
} catch (Exception ex){
throw new MyCustomPersistenceException("Could not doSomething", e);
}
}
如果1和2成功而3失敗,1和2上的交易是否會回滾?
如果第三個操作失敗,則第一個和第二個操作將回滾。 但如果它們是同一事務或事務上下文的一部分。
例如,如果將事務管理器定義為DataSourceTransactionManager,它將回滾同一連接的JDBC操作。 在您的情況下,您在同一方法中擁有所有三個操作並使用相同的jdbcTemplate,因此它將回滾您的其他兩個事務。
如果使sql指令失敗,您可以測試這個,例如:
你可以在這里看到更多http://www.journaldev.com/2603/spring-transaction-management-jdbc-example
http://docs.spring.io/autorepo/docs/spring/4.2.x/spring-framework-reference/html/transaction.html
關於返回布爾值我認為拋出異常更好,它會自動回滾事務。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.