目 的: 初步了解两种常用的事务隔离级别Committed Read和Last Committed Read
两种隔离级别描述:
Committed Read:
此隔离级别能确保所有的记录都是提交到数据库,因而能避免读取到脏数据,能确保所有读取到的记录都是已提交的,当一个进程读完记录后,其它进程就可以修改。
在读取数据前,数据库服务器尝试在记录上加共享锁。加锁前,需要先检查是否可以对对象加共享锁;如果可以加锁,则要保证要加锁的记录没有其他进程正在更新;当继续正在更新时,记录上有排他锁,此时我们不能对记录加共享锁。
命令参考:SET ISOLATION TO COMMITTED READ ;
Last Committed Read:
这是一种乐观锁,它解决了Commited Read的不足,因为Commited Read在记录被锁时,其它进程需要等待。
此隔离级别常被用在WEB应用系统中,例如在电子商务系统中,可以选择商品添加到购物篮中,但是此时后台可能你正在对商品的价格进行更新,当再次检查的时候,可能发现商品的价格已经发生变化。
相对Committed Read而言,提高了并发量和系统的吞吐量。可以通过ONCONFIG参数设置为隔离级别:USELASTCOMMITTED。且表需要设置为行级锁,不能是页级锁。
命令参考:SET ISOLATION TO COMMITTED READ LAST COMMITTED;
测试场景:
分别在隔离级别COMMITTED READ与LAST COMMITTED READ下,设置超时模式lock mode to wait 5,测试不同会话之间的交互情况:其中一个会话包含DML的事务在长时间不提交或回滚,与另一会话的Select操作同一笔数据的情况对比。
表tt结构如下,设置为行锁模式:
create table tt
(id integer,
Name varchar(30)
) extent size 16 netxt size 16 lock mode row;
一.隔离级别为Committed Read
1.删除与查询并发
Session A: 删除id=4的记录,但不提交或回滚。等待Session B操作。
Session B: 当select查询访问到id=4的记录时,等待5秒后出现锁超时Lock Time Expired.
2.修改与查询并发
Session A: 修改id=5的数据,但不提交或回滚。等待Session B操作。
Session B: 当select查询访问到id=5的记录时,等待5秒后出现锁超时Lock Time Expired.
3.插入与查询并发
Session A: 插入id=5的数据,但不提交或回滚。等待Session B操作。
Session 2: 当select查询表访问到id=5的记录时,等待5秒后出现锁超时Lock Time Expired.
二.隔离级别为Last Committed Read
1.删除与查询并发
Session A: 删除id=2的记录,但不提交或回滚。等待Session B操作。
Session B: 当select查询记录id=2时,为最后一次提交的数据。
2.修改与查询并发
Session A: 修改id=3的记录,但不提交或回滚。等待Session B操作。
Session B: Select访问到的是id=3修改之前的数据记录。
3.修改与查询并发
Session A: 插入id=8的记录,但不提交或回滚。等待Session B操作。
Session B: select访问到的是插入之前的表数据, 不包含id=8的数据。
三.测试结果对比
从以上简单测试看出:两种隔离级别测试相同场景,得到的结果则不相同。
-
committed read: DML持有独占锁,其他进程只能等待锁释放,session B的 select无法加共享锁,不可读取未提交的表数据。
-
last committed read: DML持有独占锁,但属于乐观锁,其他会话select 可以访问数据,但读取到的为最近一次提交的数据。前提为表需设置为行级锁。