达梦事务管理之事务隔离级别

目录

1.DM事务隔离级别

1.1读提交隔离级

1.2读未提交隔离级

1.3串行化隔离级

1.4隔离级别表

2.测试

2.1读未提交隔离级

2.2串行化隔离级


本文第1部分介绍了达梦数据库的3种事务隔离级别,第2部分通过测试观察不同级别之间的区别。

1.DM事务隔离级别

        DM数据库支持三种事务隔离级别:读未提交、读提交和串行化。其中,读提交是DM数据库默认使用的事务隔离级别。

1.1读提交隔离级

        DM 数据库的读提交隔离可以确保只访问到已提交事务修改的数据,保证数据处于一致

性状态,能够满足大多数应用的要求,并最大限度的保证系统并发性能。

        用户可以在事务开始时使用以下语句设定事务为读提交隔离级:

SQL> SET TRANSACTION ISOLATION LEVEL READ COMMITTED;

1.2读未提交隔离级

        读未提交隔离级别是最不严格的隔离级别。实际上,在使用这个隔离级别时,有可能发生脏读、不可重复读和幻像。一般来说,读未提交隔离级别通常只用于访问只读表和只读视图,以消除可见性判断带来的系统开销,提升查询性能。

        用户可以在事务开始时使用以下语句,设定事务为读未提交隔离级:

SQL> SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;

        此外,DM 还允许用户在 SELECT 语句的末尾加上 WITH UR 以指定当前查询语句的隔离级为读未提交,即允许脏读,并在该语句结束时自动恢复为原来的隔离级。

1.3串行化隔离级

        在要求消除不可重复读取或幻读的情况下,我们可以设置事务隔离级为串行化。

        用户可以在事务开始时使用以下语句设定事务为串行化隔离级:

SQL> SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;

1.4隔离级别表

        在 SQL-92 标准中,定义了四种隔离级别:读未提交、读提交、可重复读和串行化。每种隔离级别下对于读数据有不同的要求,下表中列出四种隔离级别下系统允许/禁止哪些类型的读数据现象。其中“Y”表示允许,“N”表示禁止。

1. 脏读(DirtyRead

所谓脏读就是对脏数据的读取,而脏数据所指的就是未提交的已修改数据。

2. 不可重复读(Non-RepeatableRead

一个事务先后读取同一条记录,但两次读取的数据不同,我们称之为不可重复读。如果

一个事务在读取了一条记录后,另一个事务修改了这条记录并且提交了事务,再次读取记录

时如果获取到的是修改后的数据,这就发生了不可重复读情况。

3. 幻读(PhantomRead

一个事务按相同的查询条件重新读取以前检索过的数据,却发现其他事务插入了满足其

查询条件的新数据,这种现象就称为幻读

2.测试

2.1读未提交隔离级

读未提交隔离级允许脏读。下面我们通过实验来观察。

1.准备测试数据

create table tb_test_uncommit (
id  int,
c1  varchar(30)
);

在会话1(会话号145566328)中,插入1条数据,不执行commit

SQL> SELECT '当前会话id:'||sessid||',当前事务id:'||id  FROM  V$TRX  t where T.SESS_ID=sessid;
SQL> insert into tb_test_uncommit values(1,'uncommit测试');

2.在新会话中测试读现象

1)新会话的ID是:139960573195272

SQL> SELECT SESSID;

2)设置读未提交隔离级

SQL> SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
SQL> select t.* from tb_test_uncommit t;

查询到了其他事务未提交的数据,发生了脏读现象

3)设置读提交隔离级

SQL> SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
SQL> select t.* from tb_test_uncommit t;

未发生脏读现象

4)设置串行化隔离级

SQL> SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
SQL> select t.* from tb_test_uncommit t;

未发生脏读现象

2.2串行化隔离级

        “串行化”与默认的“读提交”隔离级的区别在于“不可重复读”和“幻读”现象。

        举个例子:事务A查询表TB1中c1=1的数据有1条,且c2字段值是’aaa’,事务A未结束,此时事务B修改了TB1中c1=1的数据,将c2更新为’bbb’,事务B执行commit。之后,事务A第2次查询表TB1中c1=1的数据,这时看到c2的值仍然是’aaa’。这是因为串行化隔离级禁用了“不可重复读”。具体情况看下面的测试:

1.准备数据

create table tb1
(
c1 int,
c2 varchar(10)
);

INSERT INTO TB1 VALUES(1,'aaa');
commit;

2.设置串行化隔离级别,在事务A中查询数据

SQL> SET TRANSACTION ISOLATION LEVEL SERIALIZABLE; 
SQL> SELECT '当前会话id:'||sessid||',当前事务id:'||id  FROM  V$TRX  t where T.SESS_ID=sessid;
SQL> select * from TB1 where c1=1;

3.会话B修改数据,并提交

SQL> SELECT '当前会话id:'||sessid||',当前事务id:'||id  FROM  V$TRX  t where T.SESS_ID=sessid;
SQL> update TB1 set c2='bbb' where c1=1;
SQL> commit;

4.在事务A中第2次查询数据

SQL> SELECT '当前会话id:'||sessid||',当前事务id:'||id  FROM  V$TRX  t where T.SESS_ID=sessid;
SQL> select * from TB1 where c1=1;

        我们看到,B事务修改c2为‘bbb’后执行了commit,事务A看到的值还是'aaa',这是因为串行化隔离级禁用了“不可重复读”。

        幻读现象的测试步骤同上,可以将事务B中的UPDATE改为INSERT,插入几条ID值为1的数据,观察是否有幻读现象。

本文结束!

参考文档: 《DM8系统管理员手册》

日期:20240903

  • 13
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值