成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Spring官方都推薦使用的@Transactional事務(wù),為啥我不建議使用!

開發(fā) 開發(fā)工具
事務(wù)管理在系統(tǒng)開發(fā)中是不可缺少的一部分,Spring提供了很好事務(wù)管理機制,主要分為編程式事務(wù)和聲明式事務(wù)兩種。

[[347058]]

事務(wù)管理在系統(tǒng)開發(fā)中是不可缺少的一部分,Spring提供了很好事務(wù)管理機制,主要分為編程式事務(wù)和聲明式事務(wù)兩種。

關(guān)于事務(wù)的基礎(chǔ)知識,如什么是事務(wù),數(shù)據(jù)庫事務(wù)以及Spring事務(wù)的ACID、隔離級別、傳播機制、行為等,就不在這篇文章中詳細(xì)介紹了。默認(rèn)大家都有一定的了解。

本文,作者會先簡單介紹下什么是聲明式事務(wù)和編程式事務(wù),再說一下為什么我不建議使用聲明式事務(wù)。

編程式事務(wù)

基于底層的API,如PlatformTransactionManager、TransactionDefinition 和 TransactionTemplate 等核心接口,開發(fā)者完全可以通過編程的方式來進(jìn)行事務(wù)管理。

編程式事務(wù)方式需要是開發(fā)者在代碼中手動的管理事務(wù)的開啟、提交、回滾等操作。

  1. public void test() { 
  2.  
  3.       TransactionDefinition def = new DefaultTransactionDefinition(); 
  4.  
  5.       TransactionStatus status = transactionManager.getTransaction(def); 
  6.  
  7.  
  8.  
  9.        try { 
  10.  
  11.          // 事務(wù)操作 
  12.  
  13.          // 事務(wù)提交 
  14.  
  15.          transactionManager.commit(status); 
  16.  
  17.       } catch (DataAccessException e) { 
  18.  
  19.          // 事務(wù)提交 
  20.  
  21.          transactionManager.rollback(status); 
  22.  
  23.          throw e; 
  24.  
  25.       } 
  26.  

如以上代碼,開發(fā)者可以通過API自己控制事務(wù)。

聲明式事務(wù)

聲明式事務(wù)管理方法允許開發(fā)者配置的幫助下來管理事務(wù),而不需要依賴底層API進(jìn)行硬編碼。開發(fā)者可以只使用注解或基于配置的 XML 來管理事務(wù)。

  1. @Transactional 
  2.  
  3. public void test() { 
  4.  
  5.      // 事務(wù)操作   
  6.  

如上,使用@Transactional即可給test方法增加事務(wù)控制。

當(dāng)然,上面的代碼只是簡化后的,想要使用事務(wù)還需要一些配置內(nèi)容。這里就不詳細(xì)闡述了。

這兩種事務(wù),格子有各自的優(yōu)缺點,那么,各自有哪些適合的場景呢?為什么有人會拒絕使用聲明式事務(wù)呢?

聲明式事務(wù)的優(yōu)點

通過上面的例子,其實我們可以很容易的看出來,聲明式事務(wù)幫助我們節(jié)省了很多代碼,他會自動幫我們進(jìn)行事務(wù)的開啟、提交以及回滾等操作,把程序員從事務(wù)管理中解放出來。

聲明式事務(wù)管理使用了 AOP 實現(xiàn)的,本質(zhì)就是在目標(biāo)方法執(zhí)行前后進(jìn)行攔截。 在目標(biāo)方法執(zhí)行前加入或創(chuàng)建一個事務(wù),在執(zhí)行方法執(zhí)行后,根據(jù)實際情況選擇提交或是回滾事務(wù)。

使用這種方式,對代碼沒有侵入性,方法內(nèi)只需要寫業(yè)務(wù)邏輯就可以了。

但是,聲明式事務(wù)真的有這么好么?倒也不見得。

聲明式事務(wù)的粒度問題

首先,聲明式事務(wù)有一個局限,那就是他的最小粒度要作用在方法上。

也就是說,如果想要給一部分代碼塊增加事務(wù)的話,那就需要把這個部分代碼塊單獨獨立出來作為一個方法。

但是,正是因為這個粒度問題,本人并不建議過度的使用聲明式事務(wù)。

首先,因為聲明式事務(wù)是通過注解的,有些時候還可以通過配置實現(xiàn),這就會導(dǎo)致一個問題,那就是這個事務(wù)有可能被開發(fā)者忽略。

事務(wù)被忽略了有什么問題呢?

首先,如果開發(fā)者沒有注意到一個方法是被事務(wù)嵌套的,那么就可能會再方法中加入一些如RPC遠(yuǎn)程調(diào)用、消息發(fā)送、緩存更新、文件寫入等操作。

我們知道,這些操作如果被包在事務(wù)中,有兩個問題:

1、這些操作自身是無法回滾的,這就會導(dǎo)致數(shù)據(jù)的不一致??赡躌PC調(diào)用成功了,但是本地事務(wù)回滾了,可是PRC調(diào)用無法回滾了。

2、在事務(wù)中有遠(yuǎn)程調(diào)用,就會拉長整個事務(wù)。那么久會導(dǎo)致本事務(wù)的數(shù)據(jù)庫連接一直被占用,那么如果類似操作過多,就會導(dǎo)致數(shù)據(jù)庫連接池耗盡。

有些時候,即使沒有在事務(wù)中進(jìn)行遠(yuǎn)程操作,但是有些人還是可能會不經(jīng)意的進(jìn)行一些內(nèi)存操作,如運算。或者如果遇到分庫分表的情況,有可能不經(jīng)意間進(jìn)行跨庫操作。

但是如果是編程式事務(wù)的話,業(yè)務(wù)代碼中就會清清楚楚看到什么地方開啟事務(wù),什么地方提交,什么時候回滾。這樣有人改這段代碼的時候,就會強制他考慮要加的代碼是否應(yīng)該方法事務(wù)內(nèi)。

有些人可能會說,已經(jīng)有了聲明式事務(wù),但是寫代碼的人沒注意,這能怪誰。

話雖然是這么說,但是我們還是希望可以通過一些機制或者規(guī)范,降低這些問題發(fā)生的概率。

比如建議大家使用編程式事務(wù),而不是聲明式事務(wù)。因為,作者工作這么多年來,發(fā)生過不止一次開發(fā)者沒注意到聲明式事務(wù)而導(dǎo)致的故障。

因為有些時候,聲明式事務(wù)確實不夠明顯。

聲明式事務(wù)用不對容易失效

除了事務(wù)的粒度問題,還有一個問題那就是聲明式事務(wù)雖然看上去幫我們簡化了很多代碼,但是一旦沒用對,也很容易導(dǎo)致事務(wù)失效。

如以下幾種場景就可能導(dǎo)致聲明式事務(wù)失效:

1、@Transactional 應(yīng)用在非 public 修飾的方法上

2、@Transactional 注解屬性 propagation 設(shè)置錯誤

3、@Transactional 注解屬性 rollbackFor 設(shè)置錯誤

4、同一個類中方法調(diào)用,導(dǎo)致@Transactional失效

5、異常被catch捕獲導(dǎo)致@Transactional失效

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

以上幾個問題,如果使用編程式事務(wù)的話,很多都是可以避免的。

使用聲明事務(wù)失效的問題我們發(fā)生過很多次。不知道大家有沒有遇到過,我是實際遇到過的

因為Spring的事務(wù)是基于AOP實現(xiàn)的,但是在代碼中,有時候我們會有很多切面,不同的切面可能會來處理不同的事情,多個切面之間可能會有相互影響。

在之前的一個項目中,我就發(fā)現(xiàn)我們的Service層的事務(wù)全都失效了,一個SQL執(zhí)行失敗后并沒有回滾,排查下來才發(fā)現(xiàn),是因為一位同事新增了一個切面,這個切面里面做個異常的統(tǒng)一捕獲,導(dǎo)致事務(wù)的切面沒有捕獲到異常,導(dǎo)致事務(wù)無法回滾。

這樣的問題,發(fā)生過不止一次,而且不容易被發(fā)現(xiàn)。

很多人還是會說,說到底還是自己能力不行,對事務(wù)理解不透徹,用錯了能怪誰。

但是我還是那句話,我們確實無法保證所有人的能力都很高,也無法要求所有開發(fā)者都能不出錯。我們能做的就是,盡量可以通過機制或者規(guī)范,來避免或者降低這些問題發(fā)生的概率。

其實,如果大家有認(rèn)真看過阿里巴巴出的那份Java開發(fā)手冊的話,其實就能發(fā)現(xiàn),其中的很多規(guī)約并不是完完全全容易被人理解,有些也比較生硬,但是其實,這些規(guī)范都是從無數(shù)個坑里爬出來的開發(fā)者們總結(jié)出來的。

關(guān)于@Transactional的用法,規(guī)約中也有提到過,只不過規(guī)約中的觀點沒有我這么鮮明:

總結(jié)

最后,相信本文的觀點很多人都并不一定認(rèn)同,很多人會說:Spring官方都推薦無侵入性的聲明式事務(wù),你有啥資格出來BB 。

說實話,剛工作的前幾年,我也熱衷于使用聲明式事務(wù),覺得很干凈,也很"優(yōu)雅"。覺得師兄們使用編程式事務(wù)多此一舉,沒有工匠精神。

但是慢慢的,線上發(fā)生過幾次問題之后,我們復(fù)盤后發(fā)現(xiàn),很多時候你自己寫的代碼很優(yōu)雅,這完全沒問題。

但是,優(yōu)雅的同時也帶來了一些副作用,師兄們又不能批評我,因為我的用法確實沒錯…

所以,有些事,還是要痛過之后才知道。

當(dāng)然,本文并不要求大家一定要徹底不使用聲明式事務(wù),只是建議大家日后在使用事務(wù)的時候,能夠考慮到本文中提到的觀點,然后自行選擇。

【本文是51CTO專欄作者Hollis的原創(chuàng)文章,作者微信公眾號Hollis(ID:hollischuang)】

 

戳這里,看該作者更多好文

 

責(zé)任編輯:武曉燕 來源: 51CTO專欄
相關(guān)推薦

2020-11-09 09:46:27

MySQLText類型

2024-11-29 08:20:22

Autowired場景項目

2023-09-28 09:07:54

注解失效場景

2023-05-05 07:39:04

Spring事務(wù)面試

2020-12-24 18:46:11

Java序列化編程語言

2023-09-08 08:52:12

Spring注解事務(wù)

2021-07-04 14:19:03

RabbitMQ消息轉(zhuǎn)換

2023-08-29 10:51:44

2021-06-26 14:59:13

SpringTransaction執(zhí)行

2024-03-11 11:02:03

Date類JavaAPI

2025-04-11 01:00:00

線程鎖Spring事務(wù)

2020-08-19 09:45:29

Spring數(shù)據(jù)庫代碼

2021-08-01 23:18:21

Redis Golang命令

2022-04-26 21:49:55

Spring事務(wù)數(shù)據(jù)庫

2023-11-18 09:17:56

Optional代碼

2023-03-17 09:55:10

2024-01-18 13:36:00

RustGo開發(fā)

2020-12-15 10:00:31

MySQL數(shù)據(jù)庫text

2009-12-01 09:57:22

Chrome OS硬件列表

2024-06-04 00:10:00

開發(fā)拷貝
點贊
收藏

51CTO技術(shù)棧公眾號

主站蜘蛛池模板: 999久久久精品 | 人人精品| 欧美成人专区 | 久久久精 | 欧美 中文字幕 | 免费看一区二区三区 | 国产精品视频网 | 国产一区二区三区免费观看视频 | 在线视频一区二区三区 | 国产乱码精品一区二区三区中文 | 久久人| 国产精品欧美一区二区 | 9999久久| 99精品视频免费在线观看 | 综合中文字幕 | 亚欧午夜 | 国产精品视频久久久 | 国产日屁| 天堂网中文 | 一级女毛片 | 欧美一区二区三区视频在线观看 | 成人精品鲁一区一区二区 | 亚洲综合色 | 精品日韩在线 | 成人免费视频网站在线观看 | 日韩精品免费视频 | 户外露出一区二区三区 | 国产成人精品亚洲日本在线观看 | 久久久久久亚洲精品 | 久久精品二区亚洲w码 | av黄色在线| 成人不卡视频 | 国产偷录叫床高潮录音 | 亚洲精品一区久久久久久 | 国产一区| 91精品国产91久久久久久最新 | 日韩欧美中文字幕在线观看 | 国产精品毛片一区二区三区 | 四虎av电影 | 午夜伦4480yy私人影院 | 一区二区亚洲 |