事务隔离级别详细说明-达梦数据库DM8
1 环境说明
- Cpu x86
- Os Kylin v10 sp2
- dm8.1.4.80 --03134284368-20250423-270902-20149
2 事务隔离级别
- 测试表名 T_ISO
-- 以 SYSDBA 登录
-- 清理环境
DROP TABLE IF EXISTS T_ISO;
CREATE TABLE T_ISO(ID INT PRIMARY KEY, VAL INT);
INSERT INTO T_ISO VALUES(1,100);
COMMIT;
2.1 读提交隔离级别
- DM 数据库的读提交隔离可以确保只访问到已提交事务修改的数据,保证数据处于一致性状态,能够满足大多数应用的要求,并最大限度的保证系统并发性能,但可能会出现不可重复读取和幻读。
- 用户可以在事务开始时使用以下语句设定事务为 读提交 隔离级:
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
-- 1 读提交(READ COMMITTED)
--现象:会话 B 只能读到会话 A 已提交 的数据,但同一事务内重复读可能不一致(不可重复读)。
-- 会话 A
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
UPDATE T_ISO SET VAL=200 WHERE ID=1; -- 不提交
SELECT * FROM T_ISO WHERE ID=1; -- 看到 200
-- 会话 B(新开窗口)
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
SELECT * FROM T_ISO WHERE ID=1; -- 仍看到 100(脏读被阻止)
--上面参考图1
-- 回到会话 A
COMMIT;
-- 会话 B 再查
SELECT * FROM T_ISO WHERE ID=1; -- 看到 200(不可重复读出现)
--上面参考 图2
- 图 1

- 图 2

2.2 串行化隔离级
- 在要求消除不可重复读取或幻读的情况下,我们可以设置事务隔离级为串行化。跟读提交隔离级相比,串行化事务的查询本身不会增加任何代价
- 但修改数据可能引发 串行化事务被打断 错误。
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
-- 2 串行化(SERIALIZABLE)
--只有在写-写冲突时才会出现锁等待
--现象:会话 B 的查询不会阻塞/写入会被阻塞,直到会话 A 提交
-- 会话 A
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
UPDATE T_ISO SET VAL=300 WHERE ID=1; -- 不提交
-- 会话 B
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
SELECT * FROM T_ISO WHERE ID=1; -- 不被阻塞
-- 会话 B 立即返回结果,看到 300
-- 会话 B
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
UPDATE T_ISO SET VAL=301 WHERE ID=1; -- 此时才会被阻塞,直到 A commit/rollback
--参考图3,图4,图5
- 图 3

- 图 4

- 图 5

2.3 读未提交隔离级别
- DM 还允许用户在 SELECT 语句的末尾加上 WITH UR 以指定当前查询语句的隔离
级为读未提交,即 允许脏读,并在该语句结束时自动恢复为原来的隔离级。
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
-- 3读未提交(READ UNCOMMITTED)
--现象:会话 B 可脏读会话 A 未提交的修改;也可用 SELECT ISO WITH UR 临时脏读。
-- 会话 A
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
UPDATE T_ISO SET VAL=400 WHERE ID=1; -- 不提交
-- 会话 B
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
SELECT * FROM T_ISO WHERE ID=1; -- 直接看到 400(脏读)
-- 或者会话 B 不改隔离级,仅临时脏读
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
SELECT * FROM T_ISO WHERE ID=1 WITH UR; -- 同样看到 400,语句级脏读
-- 回滚 A 观察脏读消失
ROLLBACK;
--参考图6,图7
- 图 6

- 图 7

2.4 4 只读事务
- 除了前面所述的各种标准特性外,DM 数据库还支持只读事务,只读事务只能访问数据,但不能修改数据。并且只读事务不会改变事务原有的隔离级。
- 用户可以在事务开始时使用以下语句,设定事务为只读事务
SET TRANSACTION READ ONLY;
-- 4只读事务(READ ONLY)
--现象:事务内只能做 SELECT,任何 DML/DDL 都会报错;可与其他读写事务并发。
-- 会话 A
SET TRANSACTION READ ONLY;
SELECT * FROM T_ISO WHERE ID=1; -- 正常查询
UPDATE T_ISO SET VAL=500 WHERE ID=1; -- 立即报错:仅允许只读事务执行查询语句
-- 会话 B(普通读写事务)
UPDATE T_ISO SET VAL=600 WHERE ID=1;
COMMIT;
-- 会话 A 再次查询
SELECT * FROM T_ISO WHERE ID=1; -- 看到 600(读提交语义,仍只读)
--参考图8,图9,图10
- 图8

- 图9

- 图10

3 查询当前会话事务情况
-- 3 查询当前会话的事务状态信息
SELECT
CASE(ISOLATION)
WHEN 0 THEN '读未提交'
WHEN 1 THEN '读提交'
WHEN 2 THEN '可重复读'
WHEN 3 THEN '串行化'
END AS _ISOLATION,
S.SQL_TEXT,
T.*
FROM
V$TRX T,
V$SESSIONS S
WHERE
T.SESS_ID = S.SESS_ID

1825

被折叠的 条评论
为什么被折叠?



