中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁 > news >正文

訂閱號怎么做免費的視頻網(wǎng)站青島網(wǎng)站seo服務(wù)

訂閱號怎么做免費的視頻網(wǎng)站,青島網(wǎng)站seo服務(wù),專業(yè)做律師網(wǎng)站的公司,做網(wǎng)站會后期維護嗎一、背景 在 springBoot 開發(fā)過程中,我們一般都是在業(yè)務(wù)方法上添加 Transactional 注解來讓 spring 替我們管理事務(wù),但在某些特定的場景下,添加完注解之后,事務(wù)是不生效的,接下來詳細(xì)介紹下。 二、方法不是 public 2…

一、背景

? ? ? ? 在 springBoot 開發(fā)過程中,我們一般都是在業(yè)務(wù)方法上添加 @Transactional 注解來讓 spring 替我們管理事務(wù),但在某些特定的場景下,添加完注解之后,事務(wù)是不生效的,接下來詳細(xì)介紹下。

二、方法不是 public

2.1 場景描述

? ? ? ? 當(dāng)添加?@Transactional 注解的方法不是 public 類型的,事務(wù)會失效。如下代碼:

@Transactional
private void someTransactionalMethod() {// 業(yè)務(wù)邏輯
}

2.2 原因分析

????????在 Spring 中,只有 public 方法才能被 AOP 代理處理,因此如果 @Transactional 注解的方法不是 public 的,事務(wù)管理將失效。

2.3 解決方案

????????確保 @Transactional 注解的方法是 public。如下:

@Transactional
public void someTransactionalMethod() {// 業(yè)務(wù)邏輯
}

三、方法內(nèi)部調(diào)用

3.1 場景描述

????????當(dāng)一個類內(nèi)部的方法調(diào)用另一個標(biāo)注了 @Transactional 的方法時,事務(wù)管理將失效。如下代碼:

@Service
public class MyServiceImpl {public void outerMethod() {publicMethod();}	@Transactionalpublic void publicMethod() {// 業(yè)務(wù)邏輯}
}

3.2 原因分析

? ? ? ? 這是因為內(nèi)部方法方法的調(diào)用沒有經(jīng)過代理類,即在?outerMethod() 方法里面調(diào)用的 publicMethod() 方法是?MyServiceImpl 對象調(diào)用的,并不是經(jīng)過 spring 代理類來調(diào)用的,所以事務(wù)會失效。

3.3 解決方案

? ? ? ? 解決方案就是通過代理對象方法調(diào)用,使用 AOP 代理進行事務(wù)管理,如下代碼:

@Service
public class MyServiceImpl {public void outerMethod() {// 通過代理對象調(diào)用 publicMethod((MyServiceImpl) AopContext.currentProxy()).publicMethod();}	@Transactionalpublic void publicMethod() {// 業(yè)務(wù)邏輯}
}

四、未被 spring 管理

4.1 場景描述

? ? ? ? 當(dāng)一個類沒有被 spring 管理時,事務(wù)不會生效,如下代碼:

?public class MyServiceImpl {@Transactionalpublic void someTransactionalMethod() {// 業(yè)務(wù)邏輯}
}

4.2 原因分析

????????只有在 Spring 容器中管理的 bean,才能被 AOP 代理。如果 @Transactional 注解的方法所在的類沒有被 Spring 管理,事務(wù)管理將失效。

4.3 解決方案

????????確保類被 Spring 容器管理,如通過 @Service@Component 等注解。

@Service?
public class MyServiceImpl {@Transactionalpublic void someTransactionalMethod() {// 業(yè)務(wù)邏輯}
}

五、方法用 final 或 static 修飾

5.1 場景描述

????????有時候,某個方法不想被子類重寫,這時可以將該方法定義成 final 的。普通方法這樣定義是沒問題的,但如果將事務(wù)方法定義成 final,那么事務(wù)將會失效。

@Service
public class UserService {@Transactionalpublic final void add(UserModel userModel){saveData(userModel);updateData(userModel);}
}

5.2 原因分析

????????spring 事務(wù)底層使用了 aop,也就是通過 jdk 動態(tài)代理或者 cglib,幫我們生成了代理類,在代理類中實現(xiàn)的事務(wù)功能。但如果某個方法用 final 修飾了,那么在它的代理類中,就無法重寫該方法,而添加事務(wù)功能。

????????注意:如果某個方法是 static 的,同樣無法通過動態(tài)代理,變成事務(wù)方法。

5.3 解決方案

? ? ? ? 不使用 final 或者 static 修飾方法,如下:

@Service
public class UserService {@Transactionalpublic void add(UserModel userModel){saveData(userModel);updateData(userModel);}
}

六、配置不當(dāng)

6.1 場景描述

????????@Transactional 注解的一些配置屬性,可能會影響事務(wù)的行為,如下代碼:

@Transactional(readOnly = true) 
public void someTransactionalMethod() {// 業(yè)務(wù)邏輯
}

6.2 原因分析

????????配置了?readOnly=true 屬性,那么執(zhí)行增刪改操作時就會報錯。因為這個屬性指定了此方法只能進行讀操作。

6.3 解決方案

????????檢查配置的具體含義,確保其適當(dāng)應(yīng)用。

@Transactional(readOnly = false) 
public void someTransactionalMethod() {// 業(yè)務(wù)邏輯
}

七、多線程調(diào)用

7.1 場景描述

? ? ? ? spring 事務(wù)在多線程場景下,會有問題,如下代碼

@Service
public class UserService {@Autowiredprivate UserMapper userMapper;@Autowiredprivate RoleService roleService;@Transactionalpublic void add(UserModel userModel) throws Exception {userMapper.insertUser(userModel);new Thread(() -> {roleService.doOtherThing();}).start();}
}@Service
public class RoleService {@Transactionalpublic void doOtherThing() {System.out.println("保存role表數(shù)據(jù)");}
}

7.2 原因分析

????????從上面的例子中,我們可以看到事務(wù)方法 add 中,調(diào)用了事務(wù)方法 doOtherThing,但是事務(wù)方法 doOtherThing 是在另外一個線程中調(diào)用的。

????????這樣會導(dǎo)致兩個方法不在同一個線程中,獲取到的數(shù)據(jù)庫連接不一樣,從而是兩個不同的事務(wù)。如果將來?doOtherThing 方法中拋了異常,add 方法也回滾是不可能的。

????????如果看過 spring 事務(wù)源碼的朋友,可能會知道 spring 的事務(wù)是通過數(shù)據(jù)庫連接來實現(xiàn)的。當(dāng)前線程中保存了一個 mapkey 是數(shù)據(jù)源,value 是數(shù)據(jù)庫連接。

????????我們說的同一個事務(wù),其實是指同一個數(shù)據(jù)庫連接,只有擁有同一個數(shù)據(jù)庫連接才能同時提交和回滾。如果在不同的線程,拿到的數(shù)據(jù)庫連接肯定是不一樣的,所以是不同的事務(wù)。

7.3 解決方案

????????避免在多線程中使用 @Transactional,或者手動管理線程間的事務(wù)。

@Service
public class MyService {@Transactionalpublic void someTransactionalMethod() {ExecutorService executorService = Executors.newSingleThreadExecutor();executorService.submit(() -> {// 手動管理事務(wù)TransactionStatus status = transactionManager.getTransaction(new DefaultTransactionDefinition());try {// 業(yè)務(wù)邏輯transactionManager.commit(status);} catch (Exception e) {transactionManager.rollback(status);throw e;}});}
}

八、錯誤的傳播特性

8.1 場景描述

????????如果我們在手動設(shè)置 propagation 參數(shù)的時候,把傳播特性設(shè)置錯了,事務(wù)可能就不會生效,如下代碼:

@Service
public class UserService {@Transactional(propagation = Propagation.NEVER)public void add(UserModel userModel) {saveData(userModel);updateData(userModel);}
}

8.2 原因分析

????????propagation 參數(shù)的作用是指定事務(wù)的傳播特性,spring 目前支持 7 種傳播特性:

? ? ? ? EQUIRED:如果當(dāng)前上下文中存在事務(wù),則加入該事務(wù),如果不存在事務(wù),則創(chuàng)建一個事務(wù),這是默認(rèn)的傳播屬性值。

? ? ? ?SUPPORTS:如果當(dāng)前上下文中存在事務(wù),則支持事務(wù)加入事務(wù),如果不存在事務(wù),則使用非事務(wù)的方式執(zhí)行。

? ? ? ? MANDATORY:當(dāng)前上下文中必須存在事務(wù),否則拋出異常。

? ? ? ? REQUIRES_NEW:每次都會新建一個事務(wù),并且同時將上下文中的事務(wù)掛起,執(zhí)行當(dāng)前新建事務(wù)完成以后,上下文事務(wù)恢復(fù)再執(zhí)行。

? ? ? ? NOT_SUPPORTED:如果當(dāng)前上下文中存在事務(wù),則掛起當(dāng)前事務(wù),然后新的方法在沒有事務(wù)的環(huán)境中執(zhí)行。

? ? ? ? NEVER:如果當(dāng)前上下文中存在事務(wù),則拋出異常,否則在無事務(wù)環(huán)境上執(zhí)行代碼。

? ? ? ? NESTED:如果當(dāng)前上下文中存在事務(wù),則嵌套事務(wù)執(zhí)行,如果不存在事務(wù),則新建事務(wù)。

????????我們可以看到 add 方法的事務(wù)傳播特性定義成了 Propagation.NEVER,這種類型的傳播特性不支持事務(wù),如果有事務(wù)則會拋異常。

8.3 解決方案

????????目前只有這三種傳播特性才會創(chuàng)建新事務(wù):REQUIREDREQUIRES_NEWNESTED。

@Service
public class UserService {@Transactional(propagation = Propagation.REQUIRED)public void add(UserModel userModel) {saveData(userModel);updateData(userModel);}
}

九、自己吞了異常

8.1 場景描述

????????開發(fā)者在代碼中手動 try...catch 了異常,事務(wù)不會生效,如下代碼:

@Slf4j
@Service
public class UserService {@Transactionalpublic void add(UserModel userModel) {try {saveData(userModel);updateData(userModel);} catch (Exception e) {log.error(e.getMessage(), e);}}
}

8.2 原因分析

????????這種情況下 spring 事務(wù)當(dāng)然不會回滾,因為開發(fā)者自己捕獲了異常,又沒有手動拋出,換句話說就是把異常吞掉了。

8.3 解決方案

????????如果想要 spring 事務(wù)能夠正常回滾,必須拋出它能夠處理的異常。如果沒有拋異常,則 spring 認(rèn)為程序是正常的。如下代碼:

@Slf4j
@Service
public class UserService {@Transactionalpublic void add(UserModel userModel)throws Exception {saveData(userModel);updateData(userModel);}
}

十、手動拋了別的異常

8.1 場景描述

????????即使開發(fā)者沒有手動捕獲異常,但如果拋的異常不正確,spring 事務(wù)也不會回滾。如下代碼:

@Slf4j
@Service
public class UserService {@Transactionalpublic void add(UserModel userModel) throws Exception {try {saveData(userModel);updateData(userModel);} catch (Exception e) {log.error(e.getMessage(), e);throw new Exception(e);}}
}

8.2 原因分析

????????上面的這種情況,開發(fā)人員自己捕獲了異常,又手動拋出了異常:Exception,事務(wù)同樣不會回滾。

????????因為 spring 事務(wù),默認(rèn)情況下只會回滾 RuntimeException(運行時異常)和 Error(錯誤),對于普通的 Exception(非運行時異常),它不會回滾。

8.3 解決方案

? ? ? ? 別采取這種寫法。

十一、自定義了回滾異常

11.1 場景描述

????????在使用 @Transactional 注解聲明事務(wù)時,有時我們想自定義回滾的異常,spring 也是支持的??梢酝ㄟ^設(shè)置 rollbackFor 參數(shù),來完成這個功能。但如果這個參數(shù)的值設(shè)置錯了,就會引出一些莫名其妙的問題,如下代碼:

@Slf4j
@Service
public class UserService {@Transactional(rollbackFor = BusinessException.class)public void add(UserModel userModel) throws Exception {saveData(userModel);updateData(userModel);}
}

11.2 原因分析

????????如果在執(zhí)行上面這段代碼,保存和更新數(shù)據(jù)時,程序報錯了,拋了 SqlException、DuplicateKeyException 等異常。而 BusinessException 是我們自定義的異常,報錯的異常不屬于 BusinessException,所以事務(wù)也不會回滾。

????????即使 rollbackFor 有默認(rèn)值,但阿里巴巴開發(fā)者規(guī)范中,還是要求開發(fā)者重新指定該參數(shù)。

11.3 解決方案

????????如果使用默認(rèn)值,一旦程序拋出了 Exception,事務(wù)不會回滾,這會出現(xiàn)很大的 bug。所以,建議一般情況下,將該參數(shù)設(shè)置成:Exception Throwable。

http://www.risenshineclean.com/news/29605.html

相關(guān)文章:

  • 瀘縣手機網(wǎng)站建設(shè)搜搜
  • 江西南昌網(wǎng)站制作seo排名軟件價格
  • 怎么做挖礦網(wǎng)站google網(wǎng)站登錄入口
  • 建設(shè)網(wǎng)站對公司起什么作用是什么三一crm手機客戶端下載
  • wordpress 搭建圖庫太原seo排名
  • 濟南手機網(wǎng)站建設(shè)關(guān)鍵詞拓展工具有哪些
  • 安全的營銷型網(wǎng)站制作鄭州百度網(wǎng)站快速優(yōu)化
  • 域名搶注網(wǎng)站建設(shè)關(guān)鍵詞提取工具app
  • 做搜狗pc網(wǎng)站排名寧波seo入門教程
  • 武邑網(wǎng)站建設(shè)價格免費合作推廣
  • 幾百的網(wǎng)站微信seo
  • 廣西建設(shè)領(lǐng)域證書查詢官方網(wǎng)站怎么百度推廣
  • 供應(yīng)邢臺wap網(wǎng)站建設(shè)整合營銷傳播的方法包括
  • 網(wǎng)站內(nèi)鏈工作做足外貿(mào)seo是啥
  • 網(wǎng)站 建設(shè) 問題百度有效點擊軟件
  • 武漢做網(wǎng)站制作google網(wǎng)頁版入口
  • 深圳的網(wǎng)站建設(shè)公司官網(wǎng)seo公司推薦
  • 做信息網(wǎng)站能掙錢嗎360投放廣告怎么收費
  • wordpress手機版美女東莞seo外包公司
  • 襄陽市做網(wǎng)站 優(yōu)幫云長尾詞挖掘工具
  • 佛山網(wǎng)站建設(shè)模板建站b2b電子商務(wù)平臺網(wǎng)站
  • 做財經(jīng)直播網(wǎng)站商業(yè)軟文案例
  • 購物網(wǎng)站的英文app推廣接單渠道
  • 自己建個網(wǎng)站做優(yōu)化百度云盤資源搜索
  • 電子商城網(wǎng)站開發(fā)品牌推廣的三個階段
  • 網(wǎng)站開發(fā)及維護合同網(wǎng)站免費制作
  • 女生學(xué)電子商務(wù)專業(yè)好嗎seo推廣排名公司
  • 西安做行業(yè)平臺網(wǎng)站的公司重慶百度快照優(yōu)化
  • wordpress 目錄安全seo教學(xué)培訓(xùn)
  • 北海教網(wǎng)站建設(shè)全網(wǎng)營銷整合營銷