SQL Server 中的事务与错误处理
Miriam Antona
Software Engineer
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
| 脏读 | 不可重复读 | 幻读 | |
|---|---|---|---|
| READ UNCOMMITTED | 是 | 是 | 是 |
| READ COMMITTED | 否 | 是 | 是 |
| REPEATABLE READ | 否 | 否 | 是 |
| SERIALIZABLE | 否 | 否 | 否 |
WHERE 查询 -> 只锁定这些记录事务 1
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
BEGIN TRAN
SELECT * FROM customers
WHERE customer_id BETWEEN 1 AND 3;
| customer_id | first_name | last_name | ... | phone |
|-------------|------------|-----------|-----|-----------|
| 1 | Dylan | Smith | ... | 555888999 |
已锁定记录
事务 1
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
BEGIN TRAN
SELECT * FROM customers
WHERE customer_id BETWEEN 1 AND 3;
| customer_id | first_name | last_name | ... | phone |
|-------------|------------|-----------|-----|-----------|
| 1 | Dylan | Smith | ... | 555888999 |
已锁定记录
事务 2
...
...
INSERT INTO customers (customer_id, first_name, ...)
VALUES (2, 'Phantom', 'Ph', '[email protected]', 555666222);
需要等待!
事务 1
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
BEGIN TRAN
SELECT * FROM customers
WHERE customer_id BETWEEN 1 AND 3;

SELECT * FROM customers
WHERE customer_id BETWEEN 1 AND 3;
| customer_id | first_name | last_name | ... | phone |
|-------------|------------|-----------|-----|-----------|
| 1 | Dylan | Smith | ... | 555888999 |
事务 2
...
...
INSERT INTO customers (customer_id, first_name, ...)
VALUES (2, 'Phantom', 'Ph', '[email protected]', 555666222);
需要等待!
事务 1
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
BEGIN TRAN
SELECT * FROM customers
WHERE customer_id BETWEEN 1 AND 3;

SELECT * FROM customers
WHERE customer_id BETWEEN 1 AND 3;
COMMIT TRAN
事务 2
...
...
INSERT INTO customers (customer_id, first_name, ...)
VALUES (2, 'Phantom', 'Ph', '[email protected]', 555666222);
终于执行!
事务 1
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
BEGIN TRAN
SELECT * FROM customers
WHERE customer_id BETWEEN 1 AND 3;
| customer_id | first_name | last_name | ... | phone |
|-------------|------------|-----------|-----|-----------|
| 1 | Dylan | Smith | ... | 555888999 |
事务 2
...
...
INSERT INTO customers (customer_id, first_name, ...)
VALUES (200, 'Phantom', 'Ph', '[email protected]', 555666222);
已立即插入!
事务 1
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
BEGIN TRAN
SELECT * FROM customers;
| customer_id | first_name | last_name | ... | phone |
|-------------|------------|-----------| ... |-----------|
| 1 | Dylan | Smith | ... | 555888999 |
...
| 10 | Carol | York | ... | 555148988 |
锁定整张表
事务 2
...
...
INSERT INTO customers
VALUES (100, 'Phantom', 'Ph', '[email protected]', 555666222);
需要等待!
事务 1
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
BEGIN TRAN
SELECT * FROM customers;

SELECT * FROM customers;
| customer_id | first_name | last_name | ... | phone |
|-------------|------------|-----------| ... |-----------|
| 1 | Dylan | Smith | ... | 555888999 |
...
| 10 | Carol | York | ... | 555148988 |
事务 2
...
...
INSERT INTO customers
VALUES (100, 'Phantom', 'Ph', '[email protected]', 555666222);
需要等待!
事务 1
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
BEGIN TRAN
SELECT * FROM customers;

SELECT * FROM customers;
COMMIT TRAN
事务 2
...
...
INSERT INTO customers
VALUES (100, 'Phantom', 'Ph', '[email protected]', 555666222);
终于执行!
优点:
缺点:
SERIALIZABLE 事务阻塞何时使用?
SQL Server 中的事务与错误处理