SQL Server 中的事务与错误处理
Miriam Antona
Software Engineer
并发:两个或多个事务同时读取/更改共享数据。
将我们的事务与其他事务隔离
READ COMMITTED(默认)READ UNCOMMITTEDREPEATABLE READSERIALIZABLESNAPSHOTSET TRANSACTION ISOLATION LEVEL
{READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE | SNAPSHOT}
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 |
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
| 脏读 | 不可重复读 | 幻读 | |
|---|---|---|---|
| READ UNCOMMITTED | 是 | 是 | 是 |
账户 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 |
事务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
事务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
事务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
事务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 中的事务与错误处理