今天同事遇到一個問題,一起研究,最后解決,讓我對spring的事務管理又加深了印象。
先簡單說一下項目:項目是Spring和Hibernate集成的JavaEE項目,MVC架構。
外包在service層一個以get開頭的方法中寫了一些業務邏輯,分別調用了dao層的save和get方法,但是發現get的數據正常顯示,數據表中該save的並沒有存入數據表,查hibernate生成的sql也只查到了get的語句,沒有發現save的語句,也沒有報任何錯誤。很奇怪的現象,不怕報錯,就怕它不報錯~
遂檢查了一遍代碼,沒有發現嫌疑。打斷點跟蹤發現save的這玩意兒可以在程序中get得到,證明hibernate緩存中有save進去的值,可能是hibernate沒有提交save,可是寫在同一個方法中的get正常提交了。於是想到了配置問題,因為在service層配置了事務,而其他層沒有。
所以,找到了spring的配置文件:
<tx:method name="get*" propagation="REQUIRED" read-only="true"/> <tx:method name="save*" propagation="REQUIRED"/>
郝然發現其中以get開頭的service方法的事務配置了只讀屬性,而以save開頭的service方法的read-only是默認值false。
原因找到了:因為service方法是以get開頭的,所以只有讀的權限沒有寫的權限,無法提交save動作。
解決方案:
1、最簡單。方法名字別以get開頭,以其他配置了REQUIRED隔離級別前綴的字符串開頭。
2、比較規范。DAO層的基本增刪改查動作都在service層實現一遍(調用DAO),並為其配置相應權限的事務,提供統一的帶獨立事務的增刪改查服務方法,然后無論本service類內還是類外都調用這幾個基本增刪改查方法去實現業務邏輯。
筆者推薦方案2 。