INFORMIX数据库隔离级别
INFORMIX数据库隔离级别
INFORMIX 数据库隔离级别
多个事务对相同记录的并行访问,数据库提供隔离级别来控制数据的并发访问。隔离级别指定在执行并发
SQL
事务期间会出现的现象。可能会出现以下现象:
l
脏读
。
SQL
事务
T1
修改一行。然后
SQL
事务
T2
在
T1
执行
COMMIT
之前读取该行。如果
T1
接着执行
ROLLBACK
,则
T2
将已经读取一个从未提交的行,因而也可以认为是一个从未存在过的行。
l
不可重复读取
。
SQL
事务
T1
读取一行。然后
SQL
事务
T2
修改或删除该行并执行
COMMIT
。如果
T1
接着尝试重新读取该行,
T1
可能会收到修改后的值或发现该行已被删除。
l
幻像行
。
SQL
事务
T1
读取满足某些搜索条件的多行的集合
N
。然后
SQL
事务
T2
执行生成满足
SQL
事务
T1
所使用的搜索条件的一个或多个新行的
SQL
语句。如果
T1
接着使用相同的搜索条件重复原先的读取,则
T1
收到一个不同的多行的集合。
脏读,
下面通过示例说明
dirty read
(
DR
)
–
脏读
和
commited read (CR)—
提交读两种数据库并行访问策略。
设置隔离级别方法:
DR
:
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
或者
Set isolation to dirty read;
CR:
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
或者
Set isolation to commited read;
测试示例:
Create table test(t1 integer);
三个事务
T1
、
T2
、
T3
对表
test1
进行并发访问。
场景一
:
T1:
**对表
test** **进行
DML** **操作,更新表中记录。注意
sleep(30)**
begin work;
delete from test where 1=1;
sleep (30);
insert into test(t1) values(1);
insert into test(t1) values(2);
commit work;
T2:
**对表
test** **设置提交读(
CR** **),在
T1** **运行第一
SQL** **语句后启动并发运行。设置锁等待为
60 seconds**
begin work;
set lock mode to wait 60;
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
select * from test where 1=1;
sleep(13);
select * from test where 1=1;
commit work;
T3
: 对表 test **设置脏读(
DR** **),在
T1** **运行第一
SQL** 语句后启动并发运行
begin work;
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
select * from test where 1=1;
sleep(35);
select * from test where 1=1;
commit work;
输出:
事务 | 输出 1 | 输出 2 |
T2 | 等待 T1 COMMIT 后输出: 1 2 | 等待 T1 COMMIT 后输出: 1 2 |
T3 | 不等待 T1 结束,立即输出: No rows | 不等待 T1 结束 ,sleep 35 秒后输出: 1 2 |
场景二
:
T1:
**对表
test** **进行
DML** **操作,更新表中记录。注意
sleep(30)**
begin work;
delete from test where 1=1;
sleep (70);
insert into test(t1) values(1);
insert into test(t1) values(2);
commit work;
T2:
**对表
test** **设置提交读(
CR** **),在
T1** **运行第一
SQL** **语句后启动并发运行。设置锁等待为
60 seconds**
begin work;
set lock mode to wait 60;
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
select * from test where 1=1;
sleep(13);
select * from test where 1=1;
commit work;
T3
: 对表 test **设置脏读(
DR** **),在
T1** **运行第一
SQL** 语句后启动并发运行
begin work;
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
select * from test where 1=1;
sleep(35);
select * from test where 1=1;
commit work;
输出:
事务 | 输出 1 | 输出 2 |
T2 | 由于设置的锁等待时长为 60 秒,而 T1 对表 TEST 的访问时长超过 60 秒,数据库返回: -154: ISAM error: Lock Timeout Expired 事务退出 | 由于设置的锁等待时长为 60 秒,而 T1 对表 TEST 的访问时长超过 60 秒,数据库返回: -154: ISAM error: Lock Timeout Expired 事务退出 |
T3 | 不等待 T1 结束,立即输出: No rows | 不等待 T1 结束,立即输出: No rows |
场景三
:
T1:
**对表
test** **进行
DML** **操作,更新表中记录。
T2.T3** 启动后运行
begin work;
delete from test where 1=1;
sleep (10);
insert into test(t1) values(1);
insert into test(t1) values(2);
commit work;
T2:
**对表
test** **设置提交读(
CR** )
begin work;
set lock mode to wait 60;
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
select * from test where 1=1;
sleep(60);
select * from test where 1=1;
commit work;
T3
: 对表 test **设置脏读(
DR** )
begin work;
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
select * from test where 1=1;
sleep(35);
select * from test where 1=1;
commit work;
输出:
事务 | 输出 1 | 输出 2 |
T1 | 等待 T2 结束后才能执行完成后续语句 | |
T2 T2 对 TEST 进行锁定,事务提交后,其他事务才可以对表进行 DML 操作 | 1 2 | 1 2 |
T3 | 不等待 T1 结束,立即输出: No rows | 1 2 |
结论:
脏读、提交读在数据库并行访问上,提供了不同的隔离级别。在不同的情况下应该采用不一样的隔离级别。优缺点对比
访问策略 | 优点 | 缺点 |
脏读 DR | 不需要对查询的记录上锁,效率快。能提高数据的访问并发性。 | 查询数据出现现象:脏读、幻影数据 |
提交读 CR | 能有效防止脏读的出现 | 需要对查询记录加锁,以防止其他事务对所访问数据进行更新。访问效率较脏读低,同时大大降低了数据的访问并发性。多个事务间需要互相等待锁的释放,容易出现锁等待超时错误,导致事务失败。 |