@Transactional 事務註解

前言

「不積跬步無以致千里,不積小流無以成江海。」html

在進團隊以前總覺得掌握知識能夠速成,記住了就行了,可是隨着一步步的前行,發現知識真的是一點一滴積累起來的。
發現項目中好多用到@Transactional註解的地方,正好之後還有用到這個註解的地方,因而找時間看了一下事務註解的釋義和使用。mysql

事務概念以及特性

概念

事務就是「一組原子性的SQL查詢」,或者說一個獨立的工做單元。若是數據庫引擎可以成功地對數據庫應用該組查詢的所有語句,那麼就執行該組查詢。若是其中有任何一條語句由於崩潰或其餘緣由沒法執行,那麼全部的語句都不會執行。也就是說,事務內的語句,要麼所有執行成功,要麼所有執行失敗。事務用來管理 insert,update,delete 語句。

特性

事務是恢復和 併發控制的基本單位。

事務應該具備4個屬性:原子性、一致性、隔離性、持久性。這四個屬性一般稱爲ACID特性程序員

原子性(atomicity)。一個事務是一個不可分割的工做單位,事務中包括的操做要麼都作,要麼都不作。面試

一致性(consistency)。事務必須是使數據庫從一個一致性狀態變到另外一個一致性狀態。一致性與原子性是密切相關的。sql

隔離性(isolation)。一個事務的執行不能被其餘事務干擾。即一個事務內部的操做及使用的數據對併發的其餘事務是隔離的,併發執行的各個事務之間不能互相干擾。數據庫

持久性(durability)。持久性也稱永久性(permanence),指一個事務一旦提交,它對數據庫中數據的改變就應該是永久性的。接下來的其餘操做或故障不該該對其有任何影響。併發

@Transactional 事務註解的部分屬性

@Transactional 註解的屬性信息
屬性名 說明
name 當在配置文件中有多個 TransactionManager , 能夠用該屬性指定選擇哪一個事務管理器。
propagation 事務的傳播行爲,默認值爲 REQUIRED。
isolation 事務的隔離度,默認值採用 DEFAULT。
timeout 事務的超時時間,默認值爲-1。若是超過該時間限制但事務尚未完成,則自動回滾事務。
read-only 指定事務是否爲只讀事務,默認值爲 false;爲了忽略那些不須要事務的方法,好比讀取數據,能夠設置 read-only 爲 true。
rollback-for 用於指定可以觸發事務回滾的異常類型,若是有多個異常類型須要指定,各種型之間能夠經過逗號分隔。
no-rollback- for 拋出 no-rollback-for 指定的異常類型,不回滾事務。

@Transactional 註解也能夠添加到類級別上。當把@Transactional 註解放在類級別時,表示全部該類的公共方法都配置相同的事務屬性信息。
須要注意的是:
@Transactional 只能應用到 public 方法纔有效ide

回滾
回滾(Rollback)指的是程序或數據處理錯誤,將程序或數據恢復到上一次正確狀態的行爲。回滾包括程序回滾和數據回滾等類型。

刪除由一個或多個部分完成的事務執行的更新。爲保證應用程序、數據庫或系統錯誤後還原數據庫的完整性,須要使用回滾。性能

回滾泛指程序更新失敗, 返回上一次正確狀態的行爲。atom

在默認設置下,事務只在出現運行時異常(runtime exception)時回滾,而在出現受檢查異常(checked exception)時不回滾(這一行爲和EJB中的回滾行爲是一致的)。
不過,能夠聲明在出現特定受檢查異常時像運行時異常同樣回滾。一樣,也能夠聲明一個事務在出現特定的異常時不回滾,即便特定的異常是運行時異常。

回滾對程序員意味着很是嚴重的失誤。因此回滾次數每每與程序員的薪金直接聯繫。主流互聯網公司一般都將回滾定位爲最嚴重的事故。

隔離級別

事務的隔離級別定義一個事務可能受其餘併發務活動活動影響的程度,能夠把事務的隔離級別想象爲這個事務對於事物處理數據的自私程度。

在一個典型的應用程序中,多個事務同時運行,常常會爲了完成他們的工做而操做同一個數據。併發雖然是必需的,可是會致使如下問題:

1. 髒讀(Dirty read)
在事務A修改數據以後提交數據以前,這時另外一個事務B來讀取數據,若是不加控制,事務B讀取到A修改過數據,以後A又對數據作了修改再提交,則B讀到的數據是髒數據,此過程稱爲髒讀Dirty Read。
2. 不可重複讀(Nonrepeatable read)
一個事務內在讀取某些數據後的某個時間,再次讀取之前讀過的數據,卻發現其讀出的數據已經發生了變動、或者某些記錄已經被刪除了。

3. 幻讀(Phantom reads)
事務A在按查詢條件讀取某個範圍的記錄時,事務B又在該範圍內插入了新的知足條件的記錄,當事務A再次按條件查詢記錄時,會產生新的知足條件的記錄(幻行 Phantom Row)

不可重複讀與幻讀有什麼區別?

不可重複讀的重點是修改:在同一事務中,一樣的條件,第一次讀的數據和第二次讀的「數據不同」。(由於中間有其餘事務提交了修改)
幻讀的重點在於新增或者刪除:在同一事務中,一樣的條件,第一次和第二次讀出來的「記錄數不同」。(由於中間有其餘事務提交了插入/刪除)

在理想狀態下,事務之間將徹底隔離,從而能夠防止這些問題發生。然而,徹底隔離會影響性能,由於隔離常常涉及到鎖定在數據庫中的記錄(甚至有時是鎖表)。徹底隔離要求事務相互等待來完成工做,會阻礙併發。所以,能夠根據業務場景選擇不一樣的隔離級別。

總結

知識能不能理解,主要看講解的人能不能讓別人理解,看了一些關於事務的博客,發現水平真的良莠不齊,有的說了半天也不知道在說啥,個人博客也處在這個水平,可是參考了那些高水平的博客,化抽象爲具體,更易於讓人理解,畢竟對於計算機來講,抽象的東西太多了,容易讓人懂就吸引人,以前我是確定讀不下去這些資料的,看了半天看不懂,就和大部分老師講課似的只講概念,學生就算有興趣也給磨沒了,如今發現本身不是沒興趣,而是有興趣也給磨沒了,在此感謝個人團隊,感謝潘老師,讓我找到而且一直保持着興趣。

引用

面試官:你說對 MySQL 事務很熟?那我問你 10 個問題
MySQL 事務
有關Spring事務,看這一篇就足夠了

相關文章
相關標籤/搜索