事務和並發
1.事務概念
一組不可分割的操作,事務有如下屬性(ACID 屬性:Atomic Consistent Isolated Durable)
(1)原子性---Atomic
事務的原子性指的是,事務中包含的程序作為數據庫的邏輯工作單位,它所做的對數據修改操作要麼全部執行,要麼完全不執行。
(2)一致性---Consistent
事務的一致性指的是在一個事務執行之前和執行之後事務操作的對象總狀態不變
(3)分離性---Isolated
分離性指並發的事務是相互隔離的。即一個事務內部的操作及正在操作的數據必須封鎖起來,不被其它企圖進行修改的事務看到。
(4)持久性---Durable
持久性意味著當系統或介質發生故障時,確保已提交事務的更新不能丟失。即一旦一個事務提交,DBMS保證它對數據庫中數據的改變應該是永久性的
2.事務並發問題
對於同時運行的多個事務, 當這些事務訪問數據庫中相同的數據時, 如果沒有采取必要的隔離機制, 就會導致各種並發問題:
(1)髒讀:
對於兩個事務 T1, T2, T1 讀取了已經被 T2 更新但還沒有被提交的字段。 之後, 若 T2 回滾, T1讀取的內容就是臨時且無效的.
(2)不可重復讀:
對於兩個事物 T1, T2, T1 讀取了一個字段, 然後 T2 更新了該字段. 之後, T1再次讀取同一個字段, 值就不同了.
(3)幻讀:
對於兩個事物 T1, T2, T1 按照某個查詢條件從一個表中讀取記錄, 然後 T2 在該表中插入了一些新的行或者刪除某些行. 之後, T1 再次按相同查詢條件讀取同一個表, 讀到的記錄數不同
3.事務隔離級別
解決事務並發問題可以使用設置事務隔離級別,數據庫和應用程序都可以設置隔離級別
(1)數據庫的隔離級別
數據庫事務的隔離性: 數據庫系統必須具有隔離並發運行各個事務的能力, 使它們不會相互影響, 避免各種並發問題。
一個事務與其他事務隔離的程度稱為隔離級別. 數據庫規定了多種事務隔離級別, 不同隔離級別對應不同的干擾程度, 隔離級別越高, 數據一致性就越好,
但並發性越弱。
SQL ANSI SQL 標准定義了 4 種事務隔離級別,級別越高,成本越高:
4種隔離級別圖片
注:
Oracle 只支持 2 種事務隔離級別:READ COMMITED, SERIALIZABLE. Oracle 默認的事務隔離級別為: READ COMMITED
Mysql 支持4中事務隔離級別。Mysql 默認的事務隔離級別為: REPEATABLE READ
(2)在 MySql 中設置隔離級別
(1)每啟動一個 mysql 程序, 就會獲得一個單獨的數據庫連接. 每個數據庫連接都有一個全局變量 @@tx_isolation, 表示當前的事務隔離級別. MySQL 默認的隔離級別為 Repeatable Read
(2)mysql設置手動提交/自動提交事務:set autocommit=0(手動提交)/1(自動提交)
(3)查看當前的隔離級別:
1)當前連接:SELECT @@tx_isolation;
2)全局:SELECT @@global.tx_isolation;
(4)設置當前 mySQL 連接的隔離級別:
1)set transaction isolation level read committed;
2)set session transaction isolation level read uncommitted;
(5)設置數據庫系統的全局的隔離級別:
set global transaction isolation level read committed;
(3)在 Hibernate 中設置隔離級別
JDBC 數據庫連接使用數據庫系統默認的隔離級別. 在 Hibernate 的配置文件中可以顯式的設置隔離級別. 每一個隔離級別都對應一個整數:
隔離級別 對應的整數表示
READ UNCOMMITED 1
READ COMMITED 2
REPEATABLE READ 4
SERIALIZEABLE 8
Hibernate 通過為 Hibernate 映射文件指定 hibernate.connection.isolation 屬性來設置事務的隔離級別。例:hibernate.connection.isolation = 4
注意:
Hibernate不可能改變在受管環境下由應用服務器提供的數據庫連接的隔離級別,只能通過改變應用服務器配置的方式來改變.
設置隔離級別是全局選項,會影響所有的連接和事務