自然語言處理的基本概念--結合spacy軟體的學習
-
- 1、事務的傳播行為
-
- 1.1、傳播行為簡介
- 1.2、事務的測試程式碼(這裡只測試了兩種)
- 2、事務的隔離級別
-
- 2.1、資料庫事務併發問題
- 2.2、事務的隔離級別
- 2.3、測試程式碼(這裡只測試了兩種)
1、事務的傳播行為
1.1、傳播行為簡介
當事務方法被另一個事務方法呼叫時,必須指定事務應該如何傳播。例如:方法可能繼續在現有事務中執行,也可能開啟一個新事務,並在自己的事務中執行。
事務的傳播行為可以由傳播屬性指定,Spring定義了7種類傳播行為。
傳播屬性 | 描述 |
---|---|
REQUIRED(required) | 如果有事務在執行,當前的方法就在這個事務內執行,否則,就啟動一個新的事務,並在自己的事務內執行 |
REQUIRES_NEW(required_new) | 當前的方法必須啟動新事務,並在它自己的事務內執行,如果有事務正在執行,應該將它掛起 |
SUPPORTS(supports) | 如果有事務在執行,當前的方法就在這個事務內執行,否則它可以不執行在事務中 |
NOT_SUPPORTED(not_supported) | 當前的方法不應該在事務中,如果有執行的事務,將它掛起 |
MANDATORY(mandatory) | 當前的方法必須執行在事務內部,如果沒有正在執行的事務,就丟擲異常 |
NEVER(never) | 當前的方法不應該執行在事務中,如果有執行的事務,就丟擲異常 |
NESTED(nested ) | 如果有事務在執行,當前的方法就應該在這個事務的巢狀事務內執行,否則,就啟動一個新的事務,並在它自己的事務內執行 |
事務傳播屬性可以在@Transactional註解的Propagation屬性定義
1.2、事務的測試程式碼(這裡只測試了兩種)
前景:100塊錢買兩本60元的書
propagetion:用來設定事務的傳播行為
事務的傳播行為:一個方法執行在一個開啟了事務的方法中時,當前方法是使用原來的事務還是開啟一個新的事務?
-
-Propagation.REQUIRED:預設值,使用原來的事務
一本都不會買成功
@Transactional//使用預設的事務,等價於@Transactional(propagetion = Propagation.REQUIRED) public void method1(){ method2();//呼叫method2方法 } @Transactional//method2方法也是使用預設的事務,即使用原來的事務 public void method2(){ ...//方法體 }
-Propagation.REQUIRES_NEW:將原來的事務掛起,開啟一個新的事務
-
只能買成功一本書
@Transactional//使用預設的事務,等價於@Transactional(propagetion = Propagation.REQUIRED) public void method1(){ method2();//呼叫method2方法 } @Transactional(propagetion = Propagation.REQUIRES_NEW)//method2方法使用REQUIRES_NEW事務,即使用原來的事務會被掛起,繼而開啟一個新的事務 public void method2(){ ...//方法體 }
2、事務的隔離級別
2.1、資料庫事務併發問題
假設現在有兩個事務:Transaction01和Transaction02併發執行,會出現一下的三種問題:
核心影響的是:事務的隔離性
1、髒讀:(讀到了別人未提交的事務,影響了其他事務的隔離性)
- Transaction01將某條記錄的age值從20修改為30
- Transaction02讀取了Transaction01更新後的值30
- Transaction01回滾,age值恢復到了20
- Transaction02讀取到的30就是一個無效值
2、不可重複度:(修改或刪除記錄,並且提交了事務,影響了其他事務的隔離性)
- Transaction01讀取了age值為20
- Transaction02將age值修改為30,並提交了事務
- Transaction01再次讀取age值為30,和第一次讀取的不一樣
3、幻讀:(生成一個或多個數據,提交了事務,影響了其他事務的隔離性)
- Transaction01讀取了student表中的一部分資料
- Transaction02向student表中插入了新的行
- Transaction01讀取了student表時,多出了一些行
2.2、事務的隔離級別
資料庫系統必須具有隔離併發執行各個事務的能力,使它們不會相互影響,避免各種併發問題。一個事務與其他事務隔離的程度稱為隔離級別。SQL標準中規定了多種事務隔離級別,不同隔離級別對應不同的干擾程度,隔離級別越高,資料一致性就越好,但併發性越弱。
1、讀未提交:READ_UNCOMMITTED(read_uncommitted)
允許Transaction01讀取Transaction02未提交的修改
2、讀已提交:READ_COMMITTED(read_committed)
要求Transaction01只能讀取Transaction02已提交的修改
3、可重複度:REPEATABLE_READ(repeatable_read)
確保Transaction01可以多次從一個欄位中讀取到相同的值,即Transaction01執行期間禁止其他事務對這個欄位進行更新
4、序列化:SERIALIZABLE(serializable)
確保Transaction01可以多次從一個表中讀取到相同的行,在Transaction01執行期間,禁止其他事務對這個表進行新增、更新、刪除操作。可以避免任何併發問題,但效能十分低下。
5、預設的隔離界別:
MySQL預設的隔離級別為:solation.REPEATABLE_READ
Oracle預設的隔離級別為:Isolation.READ_COMMITTED:
總結:各個隔離級別解決併發問題的能力見下表
髒讀 | 不可重複讀 | 幻讀 | |
---|---|---|---|
READ_UNCOMMITTED(read_uncommitted) | 不能 | 不能 | 不能 |
READ_COMMITTED(read_committed) | 可解決 | 不能 | 不能 |
REPEATABLE_READ(repeatable_read) | 可解決 | 可解決 | 不能 |
SERIALIZABLE(serializable) | 可解決 | 可解決 | 可解決 |
補充:各種資料庫產品對事務隔離界別的支援程度
Oracle | MySQL | |
---|---|---|
READ_UNCOMMITTED(read_uncommitted) | × | √ |
READ_COMMITTED(read_committed) | √(預設) | √ |
REPEATABLE_READ(repeatable_read) | × | √(預設) |
SERIALIZABLE(serializable) | √ | √ |
2.3、測試程式碼(這裡只測試了兩種)
使用isolation標籤來設定事務的隔離級別:
- @Transactional(isolation = Isolation.REPEATABLE_READ):可重複讀,MySQL預設的隔離級別
- @Transactional(isolation = Isolation.READ_COMMITTED):讀已提交,Oracle預設的隔離級別,開發時通常使用的隔離級別
MySQL資料庫的使用方式
我們使用的事務隔離級別是可重複度,即執行操作時修改無效
我們在第一次列印age屬性後,對資料庫檔案進行了修改,第二次列印的age值沒有變化
@Transactional//使用預設的隔離界別,由於是MySQL資料庫,所以等價於@Transactional(isolation = Isolation.REPEATABLE_READ)
public void method1(){
System.out.println(age);
...//手動修改資料庫資料
System.out.println(age);
}
我們使用的事務是讀已提交,即執行對應的操作會對之前的操作有影響
我們第一次列印age屬性後,如果對資料庫檔案進行了修改,那麼當我們再次列印age時對應的值變為被修改以後的值
@Transactional(isolation = Isolation.READ_COMMITTED)//使用事務的隔離級別是讀已提交
public void method1(){
System.out.println(age);
...//手動修改資料庫資料
System.out.println(age);
}
隔離界別是用來解決併發問題的,不同的隔離級別解決不同的問題