這篇文章主要介紹“spring事務(wù)失效的原因有哪些”,在日常操作中,相信很多人在spring事務(wù)失效的原因有哪些問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”spring事務(wù)失效的原因有哪些”的疑惑有所幫助!接下來,請跟著小編一起來學(xué)習(xí)吧!
目前成都創(chuàng)新互聯(lián)已為1000多家的企業(yè)提供了網(wǎng)站建設(shè)、域名、網(wǎng)頁空間、網(wǎng)站托管、服務(wù)器租用、企業(yè)網(wǎng)站設(shè)計、沂水網(wǎng)站維護等服務(wù),公司將堅持客戶導(dǎo)向、應(yīng)用為本的策略,正道將秉承"和諧、參與、激情"的文化,與客戶和合作伙伴齊心協(xié)力一起成長,共同發(fā)展。
Spring 事務(wù)的本質(zhì)其實就是數(shù)據(jù)庫對事務(wù)的支持,沒有數(shù)據(jù)庫的事務(wù)支持,spring 是無法提供事務(wù)功能的。真正的數(shù)據(jù)庫層的事務(wù)提交和回滾是在binlog提交之后進行提交的 通過 redo log 來重做, undo log來回滾。
一般我們在程序里面使用的都是在方法上面加@Transactional
注解,這種屬于聲明式事務(wù)。
聲明式事務(wù)本質(zhì)是通過 AOP 功能,對方法前后進行攔截,將事務(wù)處理的功能編織到攔截的方法中,也就是在目標(biāo)方法開始之前加入一個事務(wù),在執(zhí)行完目標(biāo)方法之后根據(jù)執(zhí)行情況提交或者回滾事務(wù)。
這里以 MySQL 為例,其 MyISAM 引擎是不支持事務(wù)操作的,InnoDB 才是支持事務(wù)的引擎,一般要支持事務(wù)都會使用 InnoDB
@Service public class UserServiceImpl implements UserService { public void update(User user) { updateUser(user); } @Transactional(rollbackFor = Exception.class) public void updateUser(User user) { // update user } }
上面的這種情況下是不會有事務(wù)管理操作的。
通過看聲明式事務(wù)的原理可知,spring使用的是AOP切面的方式,本質(zhì)上使用的是動態(tài)代理來達到事務(wù)管理的目的,當(dāng)前類調(diào)用的方法上面加@Transactional
這個是沒有任何作用的,因為調(diào)用這個方法的是this
.
OK, 我們在看下面的一種例子。
@Service public class UserServiceImpl implements UserService { @Transactional(rollbackFor = Exception.class) public void update(User user) { updateUser(user); } @Transactional(propagation = Propagation.REQUIRES_NEW) public void updateUser(User user) { // update user } }
這次在 update 方法上加了 @Transactional
,updateUser 加了 REQUIRES_NEW
新開啟一個事務(wù),那么新開的事務(wù)管用么?
答案是:不管用!
因為它們發(fā)生了自身調(diào)用,就調(diào)該類自己的方法,而沒有經(jīng)過 Spring 的代理類,默認(rèn)只有在外部調(diào)用事務(wù)才會生效,這也是老生常談的經(jīng)典問題了。
@Service public class UserServiceImpl implements UserService { @Transactional(rollbackFor = Exception.class) private void updateUser(User user) { // update user } }
private
方法是不會被spring代理的,因此是不會有事務(wù)產(chǎn)生的,這種做法是無效的。
//@Service public class UserServiceImpl implements UserService { @Transactional(rollbackFor = Exception.class) public void updateUser(User user) { // update user } }
沒有被spring管理的bean, spring連代理對象都無法生成,當(dāng)然無效咯。
@Service public class UserServiceImpl implements UserService { @Transactional(propagation = Propagation.NOT_SUPPORTED) public void update(User user) { // update user } }
回顧一下spring的事務(wù)傳播行為
Spring 事務(wù)的傳播行為說的是,當(dāng)多個事務(wù)同時存在的時候, Spring 如何處理這些事務(wù)的行為。
PROPAGATION_REQUIRED:如果當(dāng)前沒有事務(wù),就創(chuàng)建一個新事務(wù),如果當(dāng)前存在事務(wù),就加入該事務(wù),該設(shè)置是最常用的設(shè)置。
PROPAGATION_SUPPORTS:支持當(dāng)前事務(wù),如果當(dāng)前存在事務(wù),就加入該事務(wù),如果當(dāng)前不存在事務(wù),就以非事務(wù)執(zhí)行
PROPAGATION_MANDATORY:支持當(dāng)前事務(wù),如果當(dāng)前存在事務(wù),就加入該事務(wù),如果當(dāng)前不存在事務(wù),就拋出異常。
PROPAGATION_REQUIRES_NEW:創(chuàng)建新事務(wù),無論當(dāng)前存不存在事務(wù),都創(chuàng)建新事務(wù)。
PROPAGATION_NOT_SUPPORTED:以非事務(wù)方式執(zhí)行操作,如果當(dāng)前存在事務(wù),就把當(dāng)前事務(wù)掛起。
PROPAGATION_NEVER: 以非事務(wù)方式執(zhí)行,如果當(dāng)前存在事務(wù),則拋出異常。
PROPAGATION_NESTED:如果當(dāng)前存在事務(wù),則在嵌套事務(wù)內(nèi)執(zhí)行。如果當(dāng)前沒有事務(wù),則按 REQUIRED 屬性執(zhí)行
當(dāng)傳播行為設(shè)置了PROPAGATION_NOT_SUPPORTED,PROPAGATION_NEVER,PROPAGATION_SUPPORTS這三種時,就有可能存在事務(wù)不生效
@Service public class UserServiceImpl implements UserService { @Transactional(rollbackFor = Exception.class) public void update(User user) { try{ // update user }catch(Execption e){ log.error("異常",e) } } }
異常被抓了,這樣子代理類就沒辦法知道你到底有沒有錯誤,需不需要回滾,所以這種情況也是沒辦法回滾的哦。
public interface UserService { @Transactional(rollbackFor = Exception.class) public void update(User user) }
@Service public class UserServiceImpl implements UserService { public void update(User user) { // update user } }
通過元素的 "proxy-target-class" 屬性值來控制是基于接口的還是基于類的代理被創(chuàng)建。如果 "proxy-target-class" 屬值被設(shè)置為 "true",那么基于類的代理將起作用(這時需要CGLIB庫cglib.jar在CLASSPATH中)。如果 "proxy-target-class" 屬值被設(shè)置為 "false" 或者這個屬性被省略,那么標(biāo)準(zhǔn)的JDK基于接口的代理將起作用
注解@Transactional cglib與java動態(tài)代理最大區(qū)別是代理目標(biāo)對象不用實現(xiàn)接口,那么注解要是寫到接口方法上,要是使用cglib代理,這是注解事務(wù)就失效了,為了保持兼容注解最好都寫到實現(xiàn)類方法上。
@Service public class UserServiceImpl implements UserService { @Transactional public void update(User user) { // update user } }
到此,關(guān)于“spring事務(wù)失效的原因有哪些”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識,請繼續(xù)關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編會繼續(xù)努力為大家?guī)砀鄬嵱玫奈恼拢?/p>
文章標(biāo)題:spring事務(wù)失效的原因有哪些
當(dāng)前URL:http://jinyejixie.com/article32/igoipc.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供用戶體驗、網(wǎng)站建設(shè)、網(wǎng)站維護、App開發(fā)、微信小程序、網(wǎng)站改版
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)