注册
事务隔离级别详细说明-达梦数据库DM8
技术分享/ 文章详情 /

事务隔离级别详细说明-达梦数据库DM8

祢真伟大 2025/09/26 95 0 0

事务隔离级别详细说明-达梦数据库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
    事务隔离读提交01_20250923_145426_261.png
  • 图 2
    事务隔离读提交02_20250923_145426_261.png

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
    串行化01查询不被阻塞_20250924_095625_283.png
  • 图 4
    串行化02修改被阻塞_20250924_095625_283.png
  • 图 5
    串行化03A提交后B修改成功_20250924_095625_283.png

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
    串行化03A提交后B修改成功_20250924_095625_283.png
  • 图 7
    脏读消失02_20250924_101701_878.png

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
    只读事务01_20250924_113918_618.png
  • 图9
    只读事务02_20250924_113918_618.png
  • 图10
    只读事务03_20250924_113918_618.png

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

05_sql_20250924_141941_333.png

4 更多达梦数据库全方位指南:安装 优化 与实战教程

评论
后发表回复

作者

文章

阅读量

获赞

扫一扫
联系客服