一、什么是隔离级别
隔离级别:一个事务必须与由其他事务进行的资源或数据更改相隔离的程度。
隔离级别从允许的并发副作用(例如,脏读或虚拟读取)的角度进行描述。
SQL 标准中,定义了 4 级隔离级别及事务处理语言(TPL),防止出现如下事务隔离现象:
更新异常:一个会话能将另外一个会话未提交的数据变更(增删改)覆盖掉。通常使用数据库锁机制来避免该问题。
脏读:当前会话能读取其他会话未提交事务的数据。
不可重复读:当前会话多次执行同一条查询 SQL,其他会话对满足该 SQL 条件的数据进行更新并提交,故当前会话每次读取的数据可能与前一次的值不同。
幻读:当前会话多次执行同一条查询 SQL,其他会话对满足该 SQL 条件的数据进行新增/删除并提交,故当前会话某次读取到的数据记录可能会比前次增多或减少。
二、DM的隔离级别
达梦官方手册写的:
DM 数据库支持三种事务隔离级别:读未提交、读提交和串行化
其中,读提交是 DM 数据库默认使用的事务隔离级别。
可重复读升级为更严格的串行化隔离级。
下面我们测试下,达梦到底支持几种隔离级别?
2.1 查看当前的隔离级别
SQL> select isolation from v$trx;
LINEID ISOLATION
---------- -----------
1 1
2 1
3 1
4 1
5 1
used time: 0.297(ms). Execute id is 1419.
--1:读提交(默认)
2.2 设置隔离级别:读未提交
读未提交隔离级别是最不严格的隔离级别。实际上,在使用这个隔离级别时,有可能发生脏读、不可重复读和幻像。一般来说,读未提交隔离级别通常只用于访问只读表和只读视图,以消除可见性判断带来的系统开销,提升查询性能。
窗口一:执行update未提交
SQL> SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
executed successfully
used time: 0.213(ms). Execute id is 3507.
--查看隔离级别
SQL> select isolation from v$trx;
LINEID ISOLATION
---------- -----------
5 0
--读未提交隔离级:ISOLATION=0
SQL> select TRXID,id,name from yangkai1.tb1 where id=1;
LINEID TRXID ID NAME
---------- -------------------- ----------- ------
1 7522703 1 杨凯
used time: 0.335(ms). Execute id is 3508.
窗口二:查询
SQL> SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
executed successfully
used time: 0.201(ms). Execute id is 6505.
SQL> select TRXID,id,name from yangkai1.tb1 where id=1;
LINEID TRXID ID NAME
---------- -------------------- ----------- ------
1 7522703 1 杨凯
used time: 0.310(ms). Execute id is 6506.
结论:窗口二可以查看到窗口一未提交的数据
2.3 设置隔离级别:读已提交
DM 数据库的读提交隔离可以确保只访问到已提交事务修改的数据,保证数据处于一致性状态,能够满足大多数应用的要求,并最大限度的保证系统并发性能,但可能会出现不可重复读取和幻像读。
--窗口一
SQL> SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
executed successfully
--查看隔离级别
SQL> select isolation from v$trx;
LINEID ISOLATION
---------- -----------
5 1
--读已提交隔离级:ISOLATION=1
SQL> select TRXID,id,name from yangkai1.tb1 where id=1;
LINEID TRXID ID NAME
---------- -------------------- ----------- ------
1 7522792 1 张三
used time: 0.389(ms). Execute id is 6214.
--窗口二
SQL> SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
executed successfully
used time: 0.214(ms). Execute id is 6413.
SQL> select TRXID,id,name from yangkai1.tb1 where id=1;
LINEID TRXID ID NAME
---------- -------------------- ----------- ------
1 7522703 1 杨凯
used time: 0.407(ms). Execute id is 6414.
--没有提交,看不到的
窗口一
SQL>commit;
窗口二:
SQL> select TRXID,id,name from yangkai1.tb1 where id=1;
LINEID TRXID ID NAME
---------- -------------------- ----------- ------
1 7522792 1 张三
2.3 设置隔离级别:可重复读
SQL> SET TRANSACTION ISOLATION LEVEL repeatable read ;
executed successfully
used time: 0.380(ms). Execute id is 6216.
--查看隔离级别:
SQL> SELECT isolation FROM V$TRX;
LINEID ISOLATION
---------- -----------
5 3
--可重复读离级:ISOLATION=3
used time: 0.680(ms). Execute id is 6217.
SQL> commit;
executed successfully
used time: 0.263(ms). Execute id is 6218.
SQL> select TRXID,id,name from yangkai1.tb1 where id=1;
LINEID TRXID ID NAME
---------- -------------------- ----------- ------
1 7522792 1 张三
used time: 0.291(ms). Execute id is 6219.
--窗口一
SQL> update yangkai1.tb1 set name='王五' where id=1;
affect rows 1
used time: 0.803(ms). Execute id is 6220.
SQL> select TRXID,id,name from yangkai1.tb1 where id=1;
LINEID TRXID ID NAME
---------- -------------------- ----------- ------
1 7522873 1 王五
used time: 0.330(ms). Execute id is 6221.
--窗口二
SQL> SET TRANSACTION ISOLATION LEVEL repeatable read ;
executed successfully
used time: 0.304(ms). Execute id is 6416.
SQL> select TRXID,id,name from yangkai1.tb1 where id=1;
LINEID TRXID ID NAME
---------- -------------------- ----------- ------
1 7522792 1 张三
used time: 0.340(ms). Execute id is 6417.
--窗口一
SQL> commit;
executed successfully
used time: 4.174(ms). Execute id is 6222.
SQL>
--窗口二
SQL> select TRXID,id,name from yangkai1.tb1 where id=1;
LINEID TRXID ID NAME
---------- -------------------- ----------- ------
1 7522792 1 张三
used time: 0.332(ms). Execute id is 6418.
--此时查询到的记录和之前一致,并没有因为窗口一提交了记录发生改变
2.4 设置隔离级别:可串行读
在要求消除不可重复读取或幻像读的情况下,我们可以设置事务隔离级为串行化。跟读提交隔离级相比,串行化事务的查询本身不会增加任何代价,但修改数据可能引发“串行化事务被打断”错误。
具体来说,当一个串行化事务试图更新或删除数据时,而这些数据在此事务开始后被其他事务修改并提交时,DM 数据库将报“串行化事务被打断”错误。应用开发者应该充分考虑串行化事务带来的回滚及重做事务的开销,从应用逻辑上避免对相同数据行的激烈竞争导致产生大量事务回滚。并结合应用逻辑,捕获“串行化事务被打断”错误,进行事务重做等相应处理。如果系统中存在长时间运行的写事务,并且该长事务所操作的数据还会被其他短事务频繁更新的话,最好避免使用串行化事务。
SQL> SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
executed successfully
used time: 0.380(ms). Execute id is 6223.
--查看隔离级别:
SQL> SELECT isolation FROM V$TRX;
LINEID ISOLATION
---------- -----------
5 3
--可串行读离级:ISOLATION=3 ,为什么也是3,官方手册写的是2
---窗口一
SQL> update yangkai1.tb1 set name='李二' where id=1;
affect rows 1
used time: 0.814(ms). Execute id is 6224.
SQL> select TRXID,id,name from yangkai1.tb1 where id=1;
LINEID TRXID ID NAME
---------- -------------------- ----------- ------
1 7522875 1 李二
used time: 0.314(ms). Execute id is 6225.
---窗口二
SQL> SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
executed successfully
used time: 0.347(ms). Execute id is 6420.
SQL> select TRXID,id,name from yangkai1.tb1 where id=1;
LINEID TRXID ID NAME
---------- -------------------- ----------- ------
1 7522873 1 王五
---窗口一
SQL> commit;
executed successfully
used time: 1.380(ms). Execute id is 6226.
SQL>
--窗口二
SQL> select TRXID,id,name from yangkai1.tb1 where id=1;
LINEID TRXID ID NAME
---------- -------------------- ----------- ------
1 7522873 1 王五
used time: 0.428(ms). Execute id is 6421.
--此时查询到的记录和之前一致,并没有因为窗口一提交了记录发生改变
三、总结
通过测试,达梦是支持设置4种隔离级别。 但是可重复度和串行读的隔离级别都是3,而且功能也是一样; 也就明白为什么官方手册说只支持3种。但是官方手册有个错误。
最后修改时间:2022-12-31 16:48:14
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。





