事务隔离级别

SQL Server 中的事务与错误处理

Miriam Antona

Software Engineer

什么是并发?

并发:两个或多个事务同时读取/更改共享数据。

将我们的事务与其他事务隔离

SQL Server 中的事务与错误处理

事务隔离级别

  • READ COMMITTED(默认)
  • READ UNCOMMITTED
  • REPEATABLE READ
  • SERIALIZABLE
  • SNAPSHOT
SET TRANSACTION ISOLATION LEVEL 
    {READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE | SNAPSHOT}
SQL Server 中的事务与错误处理

查看当前隔离级别

SELECT CASE transaction_isolation_level 
    WHEN 0 THEN 'UNSPECIFIED' 
    WHEN 1 THEN 'READ UNCOMMITTED' 
    WHEN 2 THEN 'READ COMMITTED' 
    WHEN 3 THEN 'REPEATABLE READ ' 
    WHEN 4 THEN 'SERIALIZABLE' 
    WHEN 5 THEN 'SNAPSHOT' 
END AS transaction_isolation_level 
FROM sys.dm_exec_sessions 
WHERE session_id = @@SPID
| transaction_isolation_level |
|-----------------------------|
| READ COMMITTED              |
SQL Server 中的事务与错误处理

READ UNCOMMITTED

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
  • 最不严格的隔离级别
  • 可读取其他事务已修改但尚未提交或回滚的行
SQL Server 中的事务与错误处理

READ UNCOMMITTED

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
  • 最不严格的隔离级别
  • 可读取其他事务修改但未提交/未回滚的数据
脏读 不可重复读 幻读
READ UNCOMMITTED
SQL Server 中的事务与错误处理

脏读

账户 5 原始余额 = $35,000

事务1

BEGIN TRAN
  UPDATE accounts
  SET current_balance = 30000
  WHERE account_id = 5;

ROLLBACK TRAN;

事务2

...

...

...

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
SELECT current_balance
FROM accounts WHERE account_id = 5;
| current_balance |
|-----------------|
| 30000,00        |
SQL Server 中的事务与错误处理

不可重复读

事务1

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
BEGIN TRAN
    SELECT * FROM accounts WHERE account_id = 5;
| current_balance |
|-----------------|
| 35000,00        |

事务2

...

...

BEGIN TRAN
    UPDATE accounts
    SET current_balance = 30000 WHERE account_id = 5;
COMMIT TRAN
SQL Server 中的事务与错误处理

不可重复读

事务1

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
BEGIN TRAN
    SELECT * FROM accounts WHERE account_id = 5;
| current_balance |
|-----------------|
| 35000,00        |
    SELECT * FROM accounts WHERE account_id = 5;
| current_balance |
|-----------------|
| 30000,00        |

事务2

...

...

BEGIN TRAN
    UPDATE accounts
    SET current_balance = 30000 WHERE account_id = 5;
COMMIT TRAN
SQL Server 中的事务与错误处理

幻读

事务1

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
BEGIN TRAN
SELECT * FROM accounts
    WHERE current_balance BETWEEN 45000 AND 50000
| account_number       | ... | current_balance |
|----------------------|-----|-----------------|
| 55555555552020202020 | ... | 50000,00        |

事务2

...

...

BEGIN TRAN
INSERT INTO accounts
    VALUES ('55555555553939393939', 1, 45000)
COMMIT TRAN
SQL Server 中的事务与错误处理

幻读

事务1

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
BEGIN TRAN
SELECT * FROM accounts 
    WHERE current_balance BETWEEN 45000 AND 50000
| account_number       | ... | current_balance |
|----------------------|-----|-----------------|
| 55555555552020202020 | ... | 50000,00        | 
SELECT * FROM accounts 
    WHERE current_balance BETWEEN 45000 AND 50000
| account_number       |...| current_balance |
|----------------------|---|-----------------|
| 55555555553939393939 |...| 45000,00        | 幻影!
| 55555555552020202020 |...| 50000,00        |

事务2

...

...

BEGIN TRAN
INSERT INTO accounts
    VALUES ('55555555553939393939', 1, 45000)
COMMIT TRAN
SQL Server 中的事务与错误处理

READ UNCOMMITTED - 小结

优点:

  • 更快,不阻塞其他事务。

缺点:

  • 允许脏读、不可重复读和幻读。

何时使用?

  • 不想被其他事务阻塞,且可接受并发现象。
  • 明确需要查看未提交的数据。
SQL Server 中的事务与错误处理

Vamos praticar!

SQL Server 中的事务与错误处理

Preparing Video For Download...