spring事務學習的相關筆記

```

a)   傳播行爲定義了被調用方法的事務邊界。

 

傳播行爲

意義

PROPERGATION_MANDATORY

表示方法必須運行在一個事務中,如果當前事務不存在,就拋出異常

PROPAGATION_NESTED

表示如果當前事務存在,則方法應該運行在一個嵌套事務中。否則,它看起來和 PROPAGATION_REQUIRED 看起來沒什麼倆樣

PROPAGATION_NEVER

表示方法不能運行在一個事務中,否則拋出異常

PROPAGATION_NOT_SUPPORTED

表示方法不能運行在一個事務中,如果當前存在一個事務,則該方法將被掛起

PROPAGATION_REQUIRED

表示當前方法必須運行在一個事務中,如果當前存在一個事務,那麼該方法運行在這個事務中,否則,將創建一個新的事務

PROPAGATION_REQUIRES_NEW

表示當前方法必須運行在自己的事務中,如果當前存在一個事務,那麼這個事務將在該方法運行期間被掛起

PROPAGATION_SUPPORTS

表示當前方法不需要運行在一個是事務中,但如果有一個事務已經存在,該方法也可以運行在這個事務中
```
```
b)   隔離級別

在操作數據時可能帶來 3 個副作用,分別是髒讀、不可重複讀、幻讀。爲了避免這 3 中副作用的發生,在標準的 SQL 語句中定義了 4 種隔離級別,分別是未提交讀、已提交讀、可重複讀、可序列化。而在 spring 事務中提供了 5 種隔離級別來對應在 SQL 中定義的 4 種隔離級別,如下:

隔離級別

意義

ISOLATION_DEFAULT

使用後端數據庫默認的隔離級別

ISOLATION_READ_UNCOMMITTED

允許讀取未提交的數據(對應未提交讀),可能導致髒讀、不可重複讀、幻讀

ISOLATION_READ_COMMITTED

允許在一個事務中讀取另一個已經提交的事務中的數據(對應已提交讀)。可以避免髒讀,但是無法避免不可重複讀和幻讀

ISOLATION_REPEATABLE_READ

一個事務不可能更新由另一個事務修改但尚未提交(回滾)的數據(對應可重複讀)。可以避免髒讀和不可重複讀,但無法避免幻讀

ISOLATION_SERIALIZABLE

這種隔離級別是所有的事務都在一個執行隊列中,依次順序執行,而不是並行(對應可序列化)。可以避免髒讀、不可重複讀、幻讀。但是這種隔離級別效率很低,因此,除非必須,否則不建議使用。
```
```

 c)    只讀

如果在一個事務中所有關於數據庫的操作都是隻讀的,也就是說,這些操作只讀取數據庫中的數據,而並不更新數據,那麼應將事務設爲只讀模式( READ_ONLY_MARKER ) , 這樣更有利於數據庫進行優化 。

因爲只讀的優化措施是事務啓動後由數據庫實施的,因此,只有將那些具有可能啓動新事務的傳播行爲 (PROPAGATION_NESTED 、 PROPAGATION_REQUIRED 、 PROPAGATION_REQUIRED_NEW) 的方法的事務標記成只讀纔有意義。

如果使用 Hibernate 作爲持久化機制,那麼將事務標記爲只讀後,會將 Hibernate 的 flush 模式設置爲 FULSH_NEVER, 以告訴 Hibernate 避免和數據庫之間進行不必要的同步,並將所有更新延遲到事務結束。

d)   事務超時

如果一個事務長時間運行,這時爲了儘量避免浪費系統資源,應爲這個事務設置一個有效時間,使其等待數秒後自動回滾。與設

置“只讀”屬性一樣,事務有效屬性也需要給那些具有可能啓動新事物的傳播行爲的方法的事務標記成只讀纔有意義。
```
MVCC(多版本併發控制)

英文全稱爲Multi-Version Concurrency Control,樂觀鎖爲理論基礎的MVCC(多版本併發控制),MVCC的實現沒有固定的規範。每個數據庫都會有不同的實現方式。

mysql中,默認的事務隔離級別是可重複讀(repeatable-read),爲了解決不可重複讀,innodb採用了MVCC(多版本併發控制)來解決這一問題。

MVCC是利用在每條數據後面加了隱藏的兩列(創建版本號和刪除版本號),每個事務在開始的時候都會有一個遞增的版本號

新增:

insert into user (id,name,age)values(1,"張三",10);

更新:

update user set age = 11 where id = 1;

更新操作採用delete+add的方式來實現,首先將當前數據標誌爲刪除

然後新增一條新的數據:

刪除:刪除操作是直接將數據的刪除版本號更新爲當前事務的版本號

delete from user where id = 1;

查詢操作:

select * from user where id = 1;

查詢操作爲了避免查詢到舊數據或已經被其他事務更改過的數據,需要滿足如下條件:

1、查詢時當前事務的版本號需要大於或等於創建版本號

2、查詢時當前事務的版本號需要小於刪除的版本號

即:create_version <=  current_version  <  delete_version

這樣就可以避免查詢到其他事務修改的數據

補充:

1.MVCC手段只適用於Msyql隔離級別中的讀已提交(Read committed)和可重複讀(Repeatable Read).

2.Read uncimmitted由於存在髒讀,即能讀到未提交事務的數據行,所以不適用MVCC.

原因是MVCC的創建版本和刪除版本只要在事務提交後纔會產生。

3.串行化由於是會對所涉及到的表加鎖,並非行鎖,自然也就不存在行的版本控制問題。

4.通過以上總結,可知,MVCC主要作用於事務性的,有行鎖控制的數據庫模型。


```
不可重複讀和髒讀的區別是:
髒讀是某一事務讀取了另一個事務未提交的髒數據,而不可重複讀則是讀取了前一事務提交的數據。
幻讀和不可重複讀都是讀取了另一條已經提交的事務(這點就髒讀不同),所不同的是不可重複讀查詢的都是同一個數據項,而幻讀針對的是一批數據整體(比如數據的個數)。
```

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章