Oracle中事务隔离机制

事务的概念挺简单,要么全执行要么全不执行,就像银行转账,这被奉为经典案例!谈事务必提,我就不提了。事务分显示提交和隐式提交,还有一种自动提交。

显示提交必须手动敲入commit或rollback命令。DML必须显示提交,包括的命令:update、insert、delete,这几个很好理解,但select也需要显示提交,有点难理解,select只是个查询语句,而且select似乎是DQL不是DML。我们可以考虑下select into from语句,select into是一个plsql语言中的复制语句,和:=实现的目标一样。

隐式提交就是DDL、DCL,包括create、drop、alter,grant、revoke。

 

事务隔离级别:一个事务对数据库的修改与并行的另一个事务的隔离程度。

两个并发事务同时访问数据库表相同的行时,可能存在以下三个问题:

1、幻想读:事务T1读取一条指定where条件的语句,返回结果集。此时事务T2插入一行新记录,恰好满足T1的where条件。然后T1使用相同的条件再次查询,结果集中可以看到T2插入的记录,这条新纪录就是幻想。

2、不可重复读取:事务T1读取一行记录,紧接着事务T2修改了T1刚刚读取的记录,然后T1再次查询,发现与第一次读取的记录不同,这称为不可重复读。

3、脏读:事务T1更新了一行记录,还未提交所做的修改,这个T2读取了更新后的数据,然后T1执行回滚操作,取消刚才的修改,所以T2所读取的行就无效,也就是脏数据。

为了处理这些问题,SQL标准定义了以下几种事务隔离级别

READ UNCOMMITTED 幻想读、不可重复读和脏读都允许。

READ COMMITTED 允许幻想读、不可重复读,不允许脏读

REPEATABLE READ 允许幻想读,不允许不可重复读和脏读

SERIALIZABLE 幻想读、不可重复读和脏读都不允许

Oracle数据库支持READ COMMITTED(Oracle默认)和SERIALIZABLE这两种食物隔离级别。Oracle不支持脏读。

针对幻想读、不可重复读、脏读,我们举例说明:

1.两个session,右边的session中create语句完成,左面就可以查询到此表,说明create是隐式提交的。

create table t(id number primary key,name varchar2(10));

desc t;

image

2.右边的session插入两条数据,不写commit,然后查询时可以查询出插入的数据;但左边的session查询不到插入的数据

insert into t values(1,’mark’);

insert into t values(2,’judy’);

select id,name from t;

select id,name from t;

image

3.在右边的session中输入commit,然后左边的session再查询即可查询到插入的数据

commit;

select id,name from t;

image

通过2,3就可以理解insert语句需要显示提交的

4.在右边的session里查询name=judy的语句,然后在左边的session里再插入一条name=judy的语句并提交,然后再次查询在右边的session里查询

select id,name from t where name=’judy’;

insert into t values(3,’judy’);

commit;

select id,name from t where name=’judy’;

image

这步就可以理解oracle支持幻想读的。

5.右边的session里查询id=2的语句,然后左边的session里删除id=2行,开始不提交,然后再提交,分别在右边的session再次执行查询id=2的语句

select id,name from t where id=2;

delete from t where id=2;

select id,name from t where id=2;

commit;

select id,name from t where id=2;

image

这步就可以确定delete需要显示提交,oracle支持不可重复读。

6.在右边的session里更新id=1的行,然后在左边的session查询id=1,然后再在右边的session里查询,然后rollback,再查询id=1

update t set name=’judy’ where id=1;

select id,name from t where id=1;

select id,name from t where id=1;

rollback;

select id,name from t where id=1;

select id,name from t where id=1;

image

这步就可以确定update也需要显示提交的,同样确定了oracle不支持脏读。

 

有部分内容参考网上,其他纯属个人理解!

posted @ 2014-03-18 15:58  cnmarkao  阅读(1401)  评论(0编辑  收藏  举报