初始数据表数据
代码2
代码1:
BEGIN
UPDATE userinfo SET DETPGHETSYU=0 WHERE DETPGHETSYU is null;
DBMS_LOCK.SLEEP(10); --暂停10秒
commit;
END;
代码2
BEGIN
UPDATE userinfo SET DETPGHETSYU=1 WHERE DETPGHETSYU is null;
DBMS_LOCK.SLEEP(10); --暂停10秒
commit;
END;
先后在10秒内执行,最后结果为首次执行的事务(实际是首先执行update语句,也就是先拿到锁的事务)
事务1执行了10秒多多,事务2执行了17秒多,事务1在commit后释放锁后,事务2获得锁并开始执行。
恢复原数据,执行如下sql
代码1
BEGIN
UPDATE userinfo SET DETPGHETSYU=0 WHERE username='user1';
DBMS_LOCK.SLEEP(10); --暂时10秒
commit;
END;
代码2
BEGIN
UPDATE userinfo SET DETPGHETSYU=1 WHERE username='user2';
DBMS_LOCK.SLEEP(10); --暂停10秒
commit;
END;
紧挨着执行,执行后结果如下
两事务执行时间都为10秒多一点,说明事务锁是根据where后的条件锁的行。
三种需要阻止的现象(preventable phenomena)是:
1、脏读取(dirty read):一个事务读取了被其他事务写入但还未提交的数据。
2、不可重复读取(nonrepeatable read):一个事务再次读取其之前曾经读取过的数据时,发现数据已被其他已提交的事务修改或删除。
3、不存在读取、幻读(phantom read):事务按照之前的条件重新查询时,返回的结果集中包含其他已提交事务插入的满足条件的新数据。
SQL92 标准中定义了四个隔离级别,在各隔离级别中,允许发生上述三种需要阻止的现象中的一种或多种。详情见下表
现象 | 脏读取 | 不可重复读取 | 不存在读取 |
隔离级别 | |||
| |||
未提交读取(read uncommitted) | 允许 | 允许 | 允许 |
已提交读取(read committed) | 不允许 | 允许 | 允许 |
可重复读取(repeatable read) | 不允许 | 不允许 | 允许 |
串行化(rerializable) | 不允许 | 不允许 | 不允许 |
Oracle 支持三种事务隔离级别:已提交读取,串行化,以及 SQL92 中没有包含的只读模式(read-only mode)。已提交读取是 Oracle 默认使用的事务隔离级别。