SQL Server 支援 SQL-92 標準四種隔離等級,由低到高:
| 隔離等級 | 髒讀 | 不可重複讀 | 幻讀 | 說明 |
|---|---|---|---|---|
| READ UNCOMMITTED | 可能 | 可能 | 可能 | 讀取未認可資料,效能最好,僅限唯讀報表。 |
| READ COMMITTED | 防止 | 可能 | 可能 | 預設等級,僅讀取已認可資料;陳述式間資料可能變更。 |
| REPEATABLE READ | 防止 | 防止 | 可能 | 鎖定讀取範圍至交易結束;新增列仍可能產生幻讀。 |
| SERIALIZABLE | 防止 | 防止 | 防止 | 範圍鎖鎖定整個查詢範圍,並發度最低,一致性最高。 |
CREATE TABLE t_emp (
id NUMERIC(10),
name VARCHAR(10),
salary NUMERIC(10,2)
);
INSERT INTO t_emp VALUES (1,'jack',10000.50),(2,'jack2',8000.50),(3,'jack3',120000),(4,'jack4',5000),(5,'jack5',3000);
-- Session 1
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
BEGIN TRAN;
SELECT * FROM t_emp WHERE id = 1; -- 讀到 Session 2 未認可的修改
-- Session 2
BEGIN TRAN;
UPDATE t_emp SET salary = 9999 WHERE id = 1;
-- 未 COMMIT,Session 1 已讀到 9999 (髒讀)
ROLLBACK; -- Session 1 讀到的資料實際不存在
SET TRANSACTION ISOLATION LEVEL READ COMMITTED | REPEATABLE READ | SERIALIZABLE | READ UNCOMMITTED;
-- 或資料庫層級預設
ALTER DATABASE YourDB SET READ_COMMITTED_SNAPSHOT ON; -- 啟用 RCSI (行版本控制)
READ COMMITTED;長報表可用 READ UNCOMMITTED 或啟用 READ_COMMITTED_SNAPSHOT (RCSI) 避免封鎖。SERIALIZABLE 僅用於極嚴格一致性需求 (如財務結帳),並發度極低。SNAPSHOT 隔離 (行版本),讀不阻寫、寫不阻讀,需啟用 ALLOW_SNAPSHOT_ISOLATION。