spring 事務隔離級別和傳播行為_Spring事務傳播性與隔離性實戰

一、事務傳播性

1.1 什么是事務的傳播性

事務的傳播性一般在事務嵌套時候使用,比如在事務A里面調用了另外一個使用事務的方法,那么這倆個事務是各自作為獨立的事務執行提交,還是內層的事務合并到外層的事務一塊提交那,這就是事務傳播性要確定的問題。下面一一介紹比較常用的事務傳播性。

1.2 PROPAGATION_REQUIRED

Spring默認的事務傳播機制,如果外層有事務則當前事務加入到外層事務,一塊提交一塊回滾,如果外層沒有事務則當前開啟一個新事務。這個機制可以滿足大多數業務場景。

試驗:

 public class BoA { public void test(){ boB.sayHello(); }}

BoA 和boB都是進行過事務增強后的bo,那么在執行test的時候會開啟一個事務(或者test調用方已經存在事務則加入該事務),執行到sayHello()時候由于傳播性是PROPAGATION_REQUIRED,所以sayHello方法加入到test的事務,那么sayHello和test就會同時提交,同時回滾。值得注意的是如果test里面調用sayHello時候加了trycatch沒有把異常跑出去,而sayHello方法卻拋出了異常,那么整個事務也會回滾,這時候調用test的外層會受到"Transaction rolled back because it has been marked as rollback-only的異常,而把sayHello真正的異常吃掉了。

平時我們都是在bo里面調用數據庫操作,在rpc和screen調用bo,所以bo層不應該catch掉異常,而應該拋出來,在rpc和screen層catch異常。

1.3 PROPAGATION_REQUIRES_NEW

該傳播機制是每次新開啟一個事務,同時把外層的事務掛起,當前新事務執行完畢后在恢復上層事務的執行。

以上面代碼為例,首先進入test方法前會開啟一個事務,然后調用sayHello時候會把test的事務掛起,從新開啟一個新事務執行sayHello,執行完畢后恢復test的事務。如果sayHello拋出來異常則sayHello的事務會回滾,那么test方法是否回滾那?這個要看情況,如果test在調用sayHello 時候使用了trycatch并且異常沒有在catch中throw出來,那么test方法不會回滾,這時候sayHello是提交和回滾對test沒有影響,。

如果test中沒有加trycatch那么,test也會回滾。

1.4 PROPAGATION_SUPPORTS

該傳播機制如果外層有事務則加入該事務,如果不存在也不會創建新事務,直接使用非事務方式執行。

以上面代碼為例,由于PROPAGATION_SUPPORTS,所以test和sayHello都沒有開啟事務,沒啥好講的。

下面看下如果test隔離級別是PROPAGATION_REQUIRED,sayHello傳播性是PROPAGATION_SUPPORTS的情況。這時候外層test會開啟一個事務(或者test調用方已經存在事務則加入該事務),然后sayHello執行時候會加入到test的事務和1.2類似,同時提交同時回滾。

1.5 PROPAGATION_NOT_SUPPORTED

該傳播機制不支持事務,如果外層存在事務則掛起外層事務 ,然后執行當前邏輯,執行完畢后,恢復外層事務。

同樣這里看下如果test使用PROPAGATION_REQUIRED,sayHello傳播性是PROPAGATION_NOT_SUPPORTED的情況,首先test會開啟一個事務(或者test調用方已經存在事務則加入該事務),然后sayHello執行時候會掛起該事務然后在非事務內做自己的事情,做完后在恢復test的事務。 無論sayHello是否拋出異常,sayHello的事務都不會回滾,因為它不在事務范圍內,那test?

這個就和1.3一樣了,如果test catch住sayHello的異常沒有throw出去,那么test就不回滾,否者回滾。

1.6 PROPAGATION_NEVER

該傳播機制不支持事務,如果外層存在事務則直接拋出異常。

 IllegalTransactionStateException( "Existing transaction found for transaction marked with propagation 'never'")

1.7 PROPAGATION_MANDATORY

該傳播機制是說配置了該傳播性的方法只能在已經存在事務的方法中被調用,如果在不存在事務的方法中被調用,會拋出異常。

 IllegalTransactionStateException( "No existing transaction found for transaction marked with propagation 'mandatory'");

1.8 PROPAGATION_NESTED

該傳播機制特點是可以保存狀態保存點,當事務回滾后會回滾到某一個保存點上,從而避免所有嵌套事務都回滾。

上面代碼test和sayHello都設置為PROPAGATION_NESTED,如果sayHello拋出異常,兩者還是都回滾了,因為sayHello雖然回滾到了savePoint而savepoint里面確實包含了test的操作,但是savepoint后還是會吧異常throw給test,這導致了test的回滾。

總結,只有傳播性為PROPAGATION_REQUIRED||PROPAGATION_REQUIRES_NEW||PROPAGATION_NESTED時候才可能開啟一個新事務。

二、事務隔離性

2.1 什么是事務的隔離性

事務的隔離性是指多個事務并發執行的時候相互之間不受到彼此的干擾,是事務acid中i,根據隔離程度對隔離性有會分類。在具體介紹事務隔離性前有必要介紹幾個名詞說明數據庫并發操作存在的問題。

2.1.1 臟讀

所謂臟讀是指一個事務中訪問到了另外一個事務未提交的數據,具體來說假如有兩個事務A和B同時更新一個數據d=1,事務B先執行了select獲取到d=1,然后更新d=2但是沒有提交,這時候事務A在B沒有提交的情況下執行搜索結果d=2,這就是臟讀。

2.1.2 不可重復讀

所謂不可重復讀是指一個事務內在未提交的前提下多次搜索一個數據,搜出來的結果不一致。發生不可重復讀的原因是在多次搜索期間這個數據被其他事務更新了。

2.1.3 幻讀

所謂幻讀是指同一個事務內多次查詢(注意查詢的sql不一定一樣)返回的結果集的不一樣(比如新增或者少了一條數據),比如同一個事務A內第一次查詢時候有n條記錄,但是第二次同等條件下查詢卻又n+1條記錄,這就好像產生了幻覺,為啥兩次結果不一樣那。其實和不可重復讀一樣,發生幻讀的原因也是另外一個事務新增或者刪除或者修改了第一個事務結果集里面的數據。不同在于不可重復讀是數據內容被修改了,幻讀是數據變多了或者少了。

2.2、事務隔離級別

為了解決事務并發帶來的問題,才有了sql規范中的四個事務隔離級別,不同隔離級別對上面三個問題部分或者全部做了避免。注意:下面試驗用的兩個終端都是同時執行了begin為了模擬事務并發。

2.2.1 Read Uncommitted

讀未提交隔離級別,就是指一個事務中可以讀取其他事務未提交的數據,這個級別會導致臟讀。

本文都是以mysql為例引擎InnoDB,mysql默認事務隔離級別為Repeatable_Read:如圖:

99b0890d7ad44a4c5e47659244e0fdc1.png

下面我們更改隔離級別為Read Uncommitted :

33f69310dde25f66a56239f175a19c6c.png

試驗:

下面我們打開兩個mysql終端,并且關閉自動提交.

終端一:

dddeb92f35f554a8d9a7b6c776a11903.png

終端二:

5cecd015b506e6f1c164f987c910e6b1.png

終端一我們開啟了一個事務,并且插入了一條數據但是沒有提交事務,但是終端二卻查詢出來了。

終端一執行rollback:

f3e95f1686ca2686ee6f48dac01522a7.png

終端二搜索:

157ff3f026eee806d074eb7592146566.png

在終端1回滾后,終端二有搜不到了,所以有可能在終端一沒有回滾時候終端二已經獲取并使用終端一的數據,而終端一回滾后,數據已經被使用過了,所以導致了臟讀。

總結:該隔離級別會導致 臟讀,不可重復讀,幻讀,是最低級的隔離級別,一般不用的。

2.2.2 Read Committed

讀已提交隔離級別,一個事務只能讀取到其他事務已經提交的數據,可能導致同一個事務中多次搜查結果不一樣。

試驗:修改事務隔離級別為Read Committed,

c0540bb64ff3723c7f5ef9c0e550189a.png

終端一:

43d3d4e1fa37aebc473e91457d5d42d1.png

終端二:

64efb9a6807a97b7aa3a4c280144cf00.png

由于終端一執行后沒有commit,所以終端二查詢不到。

下面終端一執行commit:

19e0783af314ff56276c1d91a6bc3302.png

終端二再次執行查詢:

2f588b4cdd4f0bdb23f1f9158463cb88.png

終端一提交后,終端二就可以搜查出來了。

總結:該隔離級別會導致不可重復讀和幻讀,避免了臟讀,oracle默認是該隔離級別。實際項目使用mybaits時候雖然隔離級別是read committed,但是在一個事務中多次搜索還是會是同一個結果,這是因為mybatis一級緩存的原因

2.2.3 Repeatable Read

可重復讀隔離級別,一個事務內多次查詢數據時候查詢的數據內容和第一次查詢的一致也就是說第一次查詢出來的數據沒有被修改,而不管其他事務有沒有對這些數據新修改。但是可能其他事務新增一條數據,導致一個事務內查詢的結果集里面多了一條記錄。mysql默認隔離級別就是這個。

試驗:

首先修改事務隔離級別為可重復讀:

d3967cb8ae07f3c382de3b8a1b385a80.png

模擬修改數據情況:

終端一:

0ab249db52411963102a40e32c2c3505.png

終端二:

6d5b9a1aae9478aba9f530a5795e93f7.png

可以知道終端一已經提交的數據在終端二的事務中還是查不到(注意終端二執行begin要在終端一執行commit前,因為我們要模擬并發事務)。

下面在模擬下新增數據情況

終端一:

e195eee7128e3adca7b8b5c04f13d8ef.png

終端二:

a48866bf67913630111872ec989f39bd.png

終端一插入了一條記錄并且提交,但是終端二還是查詢不到新增的記錄

總結:這里有點奇怪,按照其他資料顯示該隔離級別應該是避免了 臟讀,不可重復讀,但是還存在幻讀,但是試驗表明不存在幻讀

2.2.4 Serializable

串行化隔離級別,就是多個事務串行化一個個按照順序執行,這種不存在并發情況,所以可以避免所有事務并發問題。

終端一:

d1f6d29fa569be43b1fb7cc98dbe377b.png

終端二:

d1c14ed50bbd0ef85958792e11b76e90.png

可以看到終端一打開一個事務后,事務二的insert語句會等待知道事務一提交或者超時。

超時:

7704144efae98797536dece6d0821beb.png

鏈接:https://www.jianshu.com/p/249f2cd42692

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/370143.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/370143.shtml
英文地址,請注明出處:http://en.pswp.cn/news/370143.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

前端為什么非要動靜分離 說一下CDN托管的意義

大型Web應用對速度的追求并沒有止步于僅僅利用瀏覽器緩存,因為瀏覽器緩存始終只是為了提升二次訪問的速度,對于首次訪問的加速,我們需要從網絡層面進行優化,最常見的手段就是CDN(Content Delivery Network,…

unity語音聊天之 www.GetAudioClip

最近在開發語音聊天功能,游戲需要跨平臺安卓與ios,上傳本地錄制的wav文件至服務器后,需要根據服務器返回的地址進行語音文件的下載并進行播放。 這里通過使用www進行下載并播放 其中在ios播放時卻不行了,查詢官方文檔后發現,ios必…

輕談BFC

BFC 定義 CSS2.1的定義 Block formatting contexts 9.4.1 Block formatting contexts Floats, absolutely positioned elements, block containers (such as inline-blocks, table-cells, and table-captions) that are not block boxes, and block boxes with overflow other …

Java中的Selenium / WebDriver示例

幾年前,我正在忙于一些工作,客戶希望了解如何解決現實世界中的問題。 他們要求我自動化woot.com網站上的某些任務。 他們的任務是訪問各個網站,并閱讀當天商品的名稱和價格。 我寫了一些Selenium代碼,以為可以將其張貼在這里&am…

c語言中怎樣實現空格的替換,C語言實現去除字符串中空格的簡單實例

在網上看了些去除空格的代碼,覺得都不是很簡潔,就自己寫代碼實現它本著高效率,不使用額外存儲空間的想法實現該功能去除空格一共有三種:1、去除全部空格;2、一種是去除左邊空格;3、去除右邊空格想去除左右兩邊空格,只要先去除左邊…

python消息隊列中間件_python-RabbtiMQ消息隊列

1.RabbitMQ簡介AMQP,即Advanced Message Queuing Protocol,高級消息隊列協議,是應用層協議的一個開放標準,為面向消息的中間件設計。消息中間件主要用于組件之間的解耦,消息的發送者無需知道消息使用者的存在&#xff…

CSS position(定位)屬性

關于CSS position,來自MDN的描述: CSS position屬性用于指定一個元素在文檔中的定位方式。top、right、bottom、left 屬性則決定了該元素的最終位置。 然后來看看什么是文檔流(normal flow),下面是 www.w3.org 的描述: Normal flo…

tomcat配置文件server.xml詳解

版權聲明:本文為博主原創文章,未經博主允許不得轉載。 目錄(?)[] 元素名 屬性 解釋 server port 指定一個端口,這個端口負責監聽關閉tomcat 的請求 shutdown 指定向端口發送的命令字符串 service name 指定service 的名字 Con…

均值,方差,協方差,協方差矩陣,特征值,特征向量

大牛博客,收藏一下 http://blog.csdn.net/yangleo1987/article/details/52845912轉載于:https://www.cnblogs.com/gaohai/p/8086626.html

Java ByteBuffer –速成課程

以我的經驗,當開發人員第一次遇到java.nio.ByteBuffer時,會引起混亂和細微的錯誤,因為如何正確使用它尚不明顯。 在我對API文檔感到滿意之前,需要反復閱讀API文檔和一些經驗以實現一些微妙之處。 這篇文章是關于如何正確使用它們的…

c語言cth三角函數表示,三角函數與雙曲函數基本公式對照表

圓函數(三角函數)1.基本性質:sin tan cos x x x ,cos cot sin xx x 1sec cos x x ,1csc sin x x tan cot 1x x sin csc 1x x sec cos 1x x 22sin cos 1x x 221tan sec x x ,221cot csc x x 2.奇偶性:sin()sin x x -- cos()cos x x - tan()tan x x --3.…

實現編輯功能有哪幾個action_Web 應用的撤銷重做實現

背景前不久,我參與開發了團隊中的一個 web 應用,其中的一個頁面操作如下圖所示:GIF這個制作間頁面有著類似 PPT 的交互:從左側的工具欄中選擇元素放入中間的畫布、在畫布中可以刪除、操作(拖動、縮放、旋轉等&#xff…

為什么我們要做三份 Webpack 配置文件

時至今日,Webpack 已經成為前端工程必備的基礎工具之一,不僅被廣泛用于前端工程發布前的打包,還在開發中擔當本地前端資源服務器(assets server)、模塊熱更新(hot module replacement)、API Pro…

使用maven插件構建docker鏡像

為什么要用插件 主要還是自動化的考慮,如果額外使用Dockerfile進行鏡像生成,可能會需要自己手動指定jar/war位置,并且打包和生成鏡像間不同步,帶來很多瑣碎的工作。 插件選擇 使用比較多的是spotify的插件:https://github.com/spo…

windows下如何安裝pip以及如何查看pip是否已經安裝成功?

最近剛學習python,發現很多關于安裝以及查看pip是否安裝成的例子都比較老,不太適合于現在(python 3.6 )因此,下一個入門級別的教程。 0:首先如何安裝python我就不做介紹了。 1:如果安裝的是pyth…

檢查用戶顯示器的分辨率

檢查用戶顯示器的分辨率 轉載于:https://www.cnblogs.com/Renyi-Fan/p/8088012.html

android 字體 dpi,詳解Android開發中常用的 DPI / DP / SP

Android的碎片化已經被噴了好多年,隨著國內手機廠商的崛起,碎片化也越來越嚴重,根據OpenSignal的最新調查,2014年市面上有18796種不同的Android設備,作為開發者,一個無法回避的難題就是需要適配各種各樣奇奇…

android studio閃退代碼不報錯_代碼不報錯,不代表真的沒錯

今天是生信星球陪你的第695天大神一句話,菜鳥跑半年。我不是大神,但我可以縮短你走彎路的半年~就像歌兒唱的那樣,如果你不知道該往哪兒走,就留在這學點生信好不好~這里有豆豆和花花的學習歷程,從新手到進階&#xff0c…

Centos7操作系統部署指南

一、硬件環境: Dell R620 二、軟件環境: Centos6.4 X86_64 KVM Windows7vnc 三、安裝說明 操作系統更新之迅速,讓作為新手的系統運維人員有點措手不及,相對于老手就胸有成竹。怎么講?由于老手對技術方向把握的非常好&…

Eclipse插件中的SLF4J登錄

一直都在使用Maven和純Java庫進行開發,我從沒想過在開發Eclipse插件時發出一些日志語句可能會成為問題。 但是,在Eclipse開發人員的想象中,一切似乎總是在Eclipse環境中,而Eclipse宇宙之外則什么都沒有。 如果您使用Google搜索上…