AVt天堂网 手机版,亚洲va久久久噜噜噜久久4399,天天综合亚洲色在线精品,亚洲一级Av无码毛片久久精品

當(dāng)前位置:首頁 > 科技  > 軟件

@Transactional注解使用以及事務(wù)失效的場景

來源: 責(zé)編: 時(shí)間:2023-09-28 10:02:49 286觀看
導(dǎo)讀一、事務(wù)的本質(zhì)1、何為事務(wù)管理數(shù)據(jù)庫事務(wù),是指作為單個(gè)邏輯工作單元執(zhí)行的一系列操作,要么完全地執(zhí)行,要么完全地不執(zhí)行。事務(wù)處理可以確保除非事務(wù)性單元內(nèi)的所有操作都成功完成,否則不會永久更新面向數(shù)據(jù)的資源。通過

一、事務(wù)的本質(zhì)

1、何為事務(wù)管理

數(shù)據(jù)庫事務(wù),是指作為單個(gè)邏輯工作單元執(zhí)行的一系列操作,要么完全地執(zhí)行,要么完全地不執(zhí)行。DaV28資訊網(wǎng)——每日最新資訊28at.com

事務(wù)處理可以確保除非事務(wù)性單元內(nèi)的所有操作都成功完成,否則不會永久更新面向數(shù)據(jù)的資源。通過將一組相關(guān)操作組合為一個(gè)要么全部成功要么全部失敗的單元,可以簡化錯(cuò)誤恢復(fù)并使應(yīng)用程序更加可靠。DaV28資訊網(wǎng)——每日最新資訊28at.com

一個(gè)邏輯工作單元要成為事務(wù),必須滿足所謂的 ACID (原子性、一致性、隔離性和持久性)屬性。事務(wù)是數(shù)據(jù)庫運(yùn)行中的邏輯工作單位。DaV28資訊網(wǎng)——每日最新資訊28at.com

2、 Spring 中的事務(wù)管理

實(shí)際工作中我們更多的是結(jié)合 Spring 來做項(xiàng)目的這時(shí)我們要滿足的情況是這種。DaV28資訊網(wǎng)——每日最新資訊28at.com

Controller層:  UserService:addUser();  Service層(UserService):   addUser(): insertUser()+ insertLog()  Dao層:   UserDao:insertUser();   LogDao: insertDao();

可以看出我們在 Service 中是可能調(diào)用多個(gè) Dao 的方法來操作數(shù)據(jù)庫中的數(shù)據(jù)的,我們要做的就是要保證 UserService 中的 addUser() 方法中的相關(guān)操作滿足事務(wù)的要求DaV28資訊網(wǎng)——每日最新資訊28at.com

常見的開啟 Spring 事務(wù)方式:@TransactionalDaV28資訊網(wǎng)——每日最新資訊28at.com

二、 @Transactional 注解

1、原理:

事務(wù)開啟后,通過 AOP 機(jī)制生成一個(gè)代理數(shù)據(jù)庫連接對象并將其放入 DataSource 實(shí)例的某個(gè) DataSourceTransactionManager 相關(guān)對象容器中。在整個(gè)事務(wù)中,業(yè)務(wù)代碼中所有的數(shù)據(jù)庫連接都應(yīng)該是同一個(gè)連接,不使用該連接的 Sql 是不會被回滾的。業(yè)務(wù)代碼出現(xiàn)異常時(shí)會執(zhí)行回滾操作DaV28資訊網(wǎng)——每日最新資訊28at.com

底層實(shí)現(xiàn):DaV28資訊網(wǎng)——每日最新資訊28at.com

圖片圖片DaV28資訊網(wǎng)——每日最新資訊28at.com

2、屬性介紹:

隔離級別( @Transactional ( isolation = Isolation.DEFAULT ) ): 為了解決數(shù)據(jù)庫容易出現(xiàn)的問題,分級加鎖處理策略DaV28資訊網(wǎng)——每日最新資訊28at.com

隔離級別
DaV28資訊網(wǎng)——每日最新資訊28at.com

描述
DaV28資訊網(wǎng)——每日最新資訊28at.com

ISOLATION_DEFAULTDaV28資訊網(wǎng)——每日最新資訊28at.com

Spring 默認(rèn)隔離級別,以連接的數(shù)據(jù)庫的事務(wù)隔離級別為準(zhǔn);Mysql (可重復(fù)讀)
DaV28資訊網(wǎng)——每日最新資訊28at.com

ISOLATION_READ_UNCOMMITTEDDaV28資訊網(wǎng)——每日最新資訊28at.com

讀未提交:最低的隔離級別,其含義是允許一個(gè)事務(wù)讀取另外一個(gè)事務(wù)沒有提交的數(shù)據(jù)。未提交讀是一種危險(xiǎn)的隔離級別,所以一般在我們實(shí)際的開發(fā)中應(yīng)用不廣,但是它的優(yōu)點(diǎn)在于并發(fā)能力高,適合那些對數(shù)據(jù)一致性沒有要求而追求高并發(fā)的場景,它的最大壞處是出現(xiàn)臟讀
DaV28資訊網(wǎng)——每日最新資訊28at.com

ISOLATION_READ_COMMITTEDDaV28資訊網(wǎng)——每日最新資訊28at.com

讀已提交:是指一個(gè)事務(wù)只能讀取另外一個(gè)事務(wù)已經(jīng)提交的數(shù)據(jù),不能讀取未提交的數(shù)據(jù)
DaV28資訊網(wǎng)——每日最新資訊28at.com

ISOLATION_REPEATABLE_READDaV28資訊網(wǎng)——每日最新資訊28at.com

可重復(fù)讀:目標(biāo)是克服讀寫提交中出現(xiàn)的不可重復(fù)讀的現(xiàn)象,因?yàn)樵谧x寫提交的時(shí)候,可能出現(xiàn)一些值的變化,影響當(dāng)前事務(wù)的執(zhí)行
DaV28資訊網(wǎng)——每日最新資訊28at.com

ISOLATION_SERIALIZABLEDaV28資訊網(wǎng)——每日最新資訊28at.com

串行化,數(shù)據(jù)庫最高的隔離級別,它會要求所有的 SQL 都會按照順序執(zhí)行,這樣就可以克服上述隔離級別出現(xiàn)的各種問題,所以它能夠完全保證數(shù)據(jù)的一致性
DaV28資訊網(wǎng)——每日最新資訊28at.com

超時(shí)時(shí)間 ( @Transactional ( timeout = 30 ) ): 定義一個(gè)事務(wù)執(zhí)行過程多久算超時(shí),以便超時(shí)后回滾。可以防止長期運(yùn)行的事務(wù)占用資源.對應(yīng)注解中的屬性 timeout (注意點(diǎn):這個(gè)超時(shí)時(shí)間在數(shù)據(jù)庫事務(wù)超時(shí)的范疇內(nèi)的)DaV28資訊網(wǎng)——每日最新資訊28at.com

是否只讀 ( @Transactional ( readOnly = true ) ):表示這個(gè)事務(wù)只讀取數(shù)據(jù)但不更新數(shù)據(jù)DaV28資訊網(wǎng)——每日最新資訊28at.com

回滾機(jī)制( @Transactional ( rollbackFor = Exception.class ):定義遇到異常時(shí)回滾策略DaV28資訊網(wǎng)——每日最新資訊28at.com

傳播機(jī)制( @Transactional ( propagation = Propagation.REQUIRED ): 對事務(wù)的傳播特性進(jìn)行定義,共有 7 種類型 (一個(gè)事務(wù)內(nèi)調(diào)用另外一個(gè)事務(wù))DaV28資訊網(wǎng)——每日最新資訊28at.com

事務(wù)行為
DaV28資訊網(wǎng)——每日最新資訊28at.com

說明
DaV28資訊網(wǎng)——每日最新資訊28at.com

PROPAGATION_REQUIRED
DaV28資訊網(wǎng)——每日最新資訊28at.com

如果當(dāng)前上下文中存在事務(wù),那么加入該事務(wù),如果不存在事務(wù),創(chuàng)建一個(gè)事務(wù),這是默認(rèn)的傳播屬性值
DaV28資訊網(wǎng)——每日最新資訊28at.com

PROPAGATION_SUPPORTS
DaV28資訊網(wǎng)——每日最新資訊28at.com

如果當(dāng)前上下文存在事務(wù),則支持事務(wù)加入事務(wù),如果不存在事務(wù),則使用非事務(wù)的方式執(zhí)行
DaV28資訊網(wǎng)——每日最新資訊28at.com

PROPAGATION_MANDATORY
DaV28資訊網(wǎng)——每日最新資訊28at.com

支持當(dāng)前事務(wù),假設(shè)當(dāng)前沒有事務(wù),就拋出異常
DaV28資訊網(wǎng)——每日最新資訊28at.com

PROPAGATION_REQUIRES_NEW
DaV28資訊網(wǎng)——每日最新資訊28at.com

每次都會新建一個(gè)事務(wù),并且同時(shí)將上下文中的事務(wù)掛起,執(zhí)行當(dāng)前新建事務(wù)完成以后,上下文事務(wù)恢復(fù)再執(zhí)行
DaV28資訊網(wǎng)——每日最新資訊28at.com

PROPAGATION_NOT_SUPPORTED
DaV28資訊網(wǎng)——每日最新資訊28at.com

如果當(dāng)前上下文中存在事務(wù),則掛起當(dāng)前事務(wù),然后新的方法在沒有事務(wù)的環(huán)境中執(zhí)行
DaV28資訊網(wǎng)——每日最新資訊28at.com

PROPAGATION_NEVER
DaV28資訊網(wǎng)——每日最新資訊28at.com

如果當(dāng)前上下文中存在事務(wù),則拋出異常,否則在無事務(wù)環(huán)境上執(zhí)行代碼
DaV28資訊網(wǎng)——每日最新資訊28at.com

PROPAGATION_NESTED
DaV28資訊網(wǎng)——每日最新資訊28at.com

如果當(dāng)前存在事務(wù),則在嵌套事務(wù)內(nèi)執(zhí)行。如果當(dāng)前沒有事務(wù),則執(zhí)行與 PROPAGATION_REQUIRED 類似的操作。
DaV28資訊網(wǎng)——每日最新資訊28at.com

三、常見的 @Transactional 注解 事務(wù)沒生效的場景

1、訪問權(quán)限問題 (只有 public 方法會生效)

示例代碼:DaV28資訊網(wǎng)——每日最新資訊28at.com

@Servicepublic class UserService {  @Transactional  private void add(UserModel userModel) {    saveData(userModel);    updateData(userModel);  }}

原因:Spring 要求被代理方法必須得是 public 的DaV28資訊網(wǎng)——每日最新資訊28at.com

圖片DaV28資訊網(wǎng)——每日最新資訊28at.com

也就是說,如果我們自定義的事務(wù)方法(即目標(biāo)方法),它的訪問權(quán)限不是 public,而是 private、 default 或 protected 的話, Spring 則不會提供事務(wù)功能DaV28資訊網(wǎng)——每日最新資訊28at.com

2、方法用 final 修飾,不會生效

示例代碼:DaV28資訊網(wǎng)——每日最新資訊28at.com

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

原因:DaV28資訊網(wǎng)——每日最新資訊28at.com

Spring 事務(wù)底層使用了 AOP,也就是通過 JDK 動態(tài)代理或者 CGLIB,幫我們生成了代理類,在代理類中實(shí)現(xiàn)的事務(wù)功能。但如果某個(gè)方法用 final 修飾了,那么在它的代理類中,就無法重寫該方法,而添加事務(wù)功能。DaV28資訊網(wǎng)——每日最新資訊28at.com

注意:如果某個(gè)方法是 static 修飾的,同樣無法通過動態(tài)代理,變成事務(wù)方法。DaV28資訊網(wǎng)——每日最新資訊28at.com

3、同一個(gè)方法內(nèi)直接調(diào)用,會造成事務(wù)失效

示例代碼:DaV28資訊網(wǎng)——每日最新資訊28at.com

@Servicepublic class UserService {  @Autowired  private UserMapper userMapper;    public void add(UserModel userModel) {    userMapper.insertUser(userModel);    updateStatus(userModel);  }  @Transactional  public void updateStatus(UserModel userModel) {    doSameThing();  }}

原因:DaV28資訊網(wǎng)——每日最新資訊28at.com

我們看到在事務(wù)方法 add 中,直接調(diào)用事務(wù)方法 updateStatus。從前面介紹的內(nèi)容可以知道, updateStatus 方法擁有事務(wù)的能力是因?yàn)?Spring AOP 生成代理了對象,但是這種方法直接調(diào)用了 this 對象的方法,并不會從 IOC 拿到加上 AOP 事務(wù)相關(guān)方法的動態(tài)代理對象 所以 updateStatus 方法不會生成事務(wù)DaV28資訊網(wǎng)——每日最新資訊28at.com

4、(類本身) 未被 Spring 管理

示例代碼:DaV28資訊網(wǎng)——每日最新資訊28at.com

//@Servicepublic class UserService {  @Transactional  public void add(UserModel userModel) {    saveData(userModel);    updateData(userModel);  }    }

原因:DaV28資訊網(wǎng)——每日最新資訊28at.com

使用 Spring 事務(wù)的前提是:對象要被 Spring IOC 管理,需要創(chuàng)建 bean 實(shí)例DaV28資訊網(wǎng)——每日最新資訊28at.com

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

示例代碼:DaV28資訊網(wǎng)——每日最新資訊28at.com

@Servicepublic class UserService {  @Autowired  private UserMapper userMapper;  @Autowired  private RoleService roleService;  @Transactional  public void add(UserModel userModel) throws Exception {    userMapper.insertUser(userModel);      new Thread(() -> {        roleService.doOtherThing();      }).start();  }}@Servicepublic class RoleService {  @Transactional  public void doOtherThing() {  }}

原因:同一個(gè)事務(wù),其實(shí)是指同一個(gè)數(shù)據(jù)庫連接,只有擁有同一個(gè)數(shù)據(jù)庫連接才能同時(shí)提交和回滾。如果在不同的線程,拿到的數(shù)據(jù)庫連接肯定是不一樣的,所以是不同的事務(wù)。DaV28資訊網(wǎng)——每日最新資訊28at.com

6、錯(cuò)誤的傳播特性

示例代碼:DaV28資訊網(wǎng)——每日最新資訊28at.com

@Servicepublic class UserService {  @Autowired  private UserMapper userMapper;  @Autowired  private RoleService roleService;    @Transactional(propagation = Propagation.REQUIRED)  public void add(UserModel userModel) throws Exception {    userMapper.insertUser(userModel);      new Thread(() -> {        roleService.doOtherThing();      }).start();  }}@Servicepublic class RoleService {  @Transactional(propagation = Propagation.NEVER)  public void doOtherThing() {  }}

原因:RoleService 中 doOtherThing() 方法上設(shè)置的事物傳播類型為 Propagation.NEVER,即存在事務(wù)就拋出異常DaV28資訊網(wǎng)——每日最新資訊28at.com

7、自己吞了異常

示例代碼:DaV28資訊網(wǎng)——每日最新資訊28at.com

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

原因:如果想要 Spring 事務(wù)能夠正常回滾,必須拋出它能夠處理的異常。如果沒有拋異常,則 Spring 認(rèn)為程序是正常的。DaV28資訊網(wǎng)——每日最新資訊28at.com

8、拋出的異常,事務(wù)管理器處理不了,則不會回滾

示例代碼:DaV28資訊網(wǎng)——每日最新資訊28at.com

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

原因:@Transactional 默認(rèn)的異常類型是 RuntimeException,如果出現(xiàn)非 RuntimeException,則 Spring 事務(wù)處理不了對應(yīng)的異常,認(rèn)為程序是正常的,則不會回滾事務(wù),此時(shí)我們可以指定異常類型如 @Transactional(rollbackFor = Exception.class)DaV28資訊網(wǎng)——每日最新資訊28at.com

9、數(shù)據(jù)庫引擎不支持事務(wù)

比如 Mysql 中的 MyISAM 引擎是不支持事務(wù)操作的, InnoDB 才是支持事務(wù)的引擎DaV28資訊網(wǎng)——每日最新資訊28at.com

四、總結(jié):

本文通過對 @Transactional 注解相關(guān)介紹,列舉出可能會出現(xiàn)事務(wù)失效的場景。發(fā)生最多就是自身調(diào)用、異常被吃、異常拋出類型不匹配這三個(gè)。由于平時(shí)業(yè)務(wù)繁重,有時(shí)候會忽視 @Transactional 注解使用規(guī)范,導(dǎo)致事務(wù)沒有生效或者沒有正常回滾,造成較大的數(shù)據(jù)異常。希望可以幫助大家日常使用 @Transactional 時(shí)避坑。DaV28資訊網(wǎng)——每日最新資訊28at.com

本文鏈接:http://www.tebozhan.com/showinfo-26-11732-0.html@Transactional注解使用以及事務(wù)失效的場景

聲明:本網(wǎng)頁內(nèi)容旨在傳播知識,若有侵權(quán)等問題請及時(shí)與本網(wǎng)聯(lián)系,我們將在第一時(shí)間刪除處理。郵件:2376512515@qq.com

上一篇: 玩轉(zhuǎn)SpringBoot—自動裝配解決Bean的復(fù)雜配置

下一篇: React中的依賴注入,看這一篇就夠了!

標(biāo)簽:
  • 熱門焦點(diǎn)
Top