并发控制中三个问题:
1、脏读
当一个事务正在访问数据,并且对数据进行了修改,而这种修改还没有提交到数据库中,这时,另外一个事务也访问这个数据,然后使用了这个数据
因为这个数据是还没有提交的数据,那么另外一个事务读到的这个数据是脏数据,依据脏数据所做的操作可能是不正确的
2、不可重复读
一个事务内,多次读同一数据。在这个事务还没有结束时,另外一个事务也访问该同一数据。那么,在第一个事务中的两次读数据之间,由于第二个事务的修改,
那么第一个事务两次读到的的数据可能是不一样的。这样就发生了在一个事务内两次读到的数据是不一样的,因此称为是不可重复读
3、幻觉读(假象读)
事务不是独立执行时发生的一种现象,例如第一个事务对一个表中的数据进行了修改,这种修改涉及到表中的全部数据行。同时,第二个事务也修改这个表中的数据,
这种修改是向表中插入一行新数据。那么,以后就会发生操作第一个事务的用户发现表中还有没有修改的数据行,就好象发生了幻觉一样
ANSI SQL中定义的4个隔离级实际上是用对锁的操作来定义的:
脏读: 读数据时不加锁。
提交读: 在读数据之前加一个读锁,读完之后释放锁。
可重复读: 在读数据之前加一个读锁,读完之后不释放锁,直到事务rollback或者commit后才释放锁。
串行化读: 在读数据之前在读取的条件上加锁(称为条件锁),读完之后不释放锁,直到事务rollback或者commit后才释放锁
以下说明了隔离级别:
static int TRANSACTION_NONE
指示事务不受支持的常量。
static int TRANSACTION_READ_COMMITTED
指示防止发生脏读的常量;不可重复读和虚读有可能发生。
static int TRANSACTION_READ_UNCOMMITTED
指示可以发生脏读 (dirty read)、不可重复读和虚读 (phantom read) 的常量。
static int TRANSACTION_REPEATABLE_READ
指示防止发生脏读和不可重复读的常量;虚读有可能发生。
static int TRANSACTION_SERIALIZABLE
指示防止发生脏读、不可重复读和虚读的常量。
TRANSACTION_NONE
static final int TRANSACTION_NONE指示事务不受支持的常量。
--------------------------------------------------------------------------------
TRANSACTION_READ_UNCOMMITTED
static final int TRANSACTION_READ_UNCOMMITTED指示可以发生脏读 (dirty read)、不可重复读和虚读 (phantom read) 的常量。此级别允许由某一事务更改的行在已提交该行中的所有更改之前被另一个事务读取(“脏读”)。如果所有更改都被回滚,则第二个事务将检索无效的行。
-------------------------------------------------------------------------------
TRANSACTION_READ_COMMITTED
static final int TRANSACTION_READ_COMMITTED指示防止发生脏读的常量;不可重复读和虚读有可能发生。此级别只禁止事务读取其中带有未提交更改的行。
--------------------------------------------------------------------------------
TRANSACTION_REPEATABLE_READ
static final int TRANSACTION_REPEATABLE_READ指示防止发生脏读和不可重复读的常量;虚读有可能发生。此级别禁止事务读取其中带有未提交更改的行,它还禁止这种情况:一个事务读取某一行,而另一个事务更改该行,第一个事务重新读取该行,并在第二次读取时获得不同的值(“不可重复读”)。
--------------------------------------------------------------------------------
TRANSACTION_SERIALIZABLE
static final int TRANSACTION_SERIALIZABLE指示防止发生脏读、不可重复读和虚读的常量。此级别包括 TRANSACTION_REPEATABLE_READ 中禁止的事项并进一步禁止出现这种情况:某一事务读取所有满足 WHERE 条件的行,另一个事务插入一个满足 WHERE 条件的行,第一个事务重新读取满足相同条件的行,并在第二次读取时检索到额外的“虚”行。
(转)http://cenjun615.blog.163.com/blog/static/51048313200942044531722/
Oracle中在事务开始之前可以通过以下方式设置隔离级别:
set transation isolation level read committed;
set transation isolation level serialezable;
set transation isolation level read only;
也可以在单独的会话中设置隔离级别:
alter session set isolation_level read committed;
alter session set isolation_level serialezable;
alter session set isolation_level read only;
1、数据库级别锁:它会锁定数据库以禁止任何新会话和新事务。锁定数据库的最主要目的是在没有用户干扰的情况下完成维护。
在Oracle中使用以下语句锁定数据库为限制模式:
alter system enable restricted session;
通过下列语句取消数据库限制模式:
alter system disable restricted session;
以下语句将锁定数据库为只读模式:
startup mount;
alter database open read only;
2、表级别锁:它会锁定整张表,以防止其它事务对表结构进行修改。比如当我们运行一个insert语句,如果表没有没锁定,其它的事务修改了一列(将列名修改),
这时我们运行update语句就会出错,所以当我们运行DML语句时,Oracle会自动将表锁定,DML语句执行完,会释放表级别锁。我们也可以通过lock语句锁定表。
3、行级别锁:当我们运行DML语句时,当前行上就会有行级别锁,防止其它事务对该行进行修改。
当我们运行DML语句时,Oracle会自动加锁,请看以下示例:
update dept set loc='北京' where deptno=40
大多数情况下,我们可以不必自己管理锁,Oracle会自动创建并管理,但是了解锁是如何工作的,对我们来说也是非常有必要的。下列这些情况Oracle会创建锁:
当我们运行了create truncate alter语句时,Oracle会创建锁,称之为DDL锁。
当我们运行了insert update delete语句,Oracle会创建锁,称之为DML锁。
还有一种是内部锁,由Oracle在内部使用,比如管理数据文件。在这里我们不做介绍。
从级别上讲,锁还可以分为数据库级别锁、表级别锁、行级别锁和列级别锁(Oracle不支持)。
锁类型:TM 锁模式:share 某个事务锁定了一张表,允许其它事务再锁定这张表,但不允许这个事务对这张表进行更新。
锁类型:TM 锁模式:row share 某个事务锁定了一张表,允许其它事务再锁定这张表中的其它行。
锁类型:TM 锁模式:row eclusive 某个事务锁定了一张表,允许其它事务以相同的锁模式锁定这张表。
锁类型:TM 锁模式:share row eclusive 在share模式基础上,不允许其它事务锁定这张表。
锁类型:TM 锁模式:eclusive 不允许其它事务再锁定该表,也不允许其它事务更新。
锁类型:TX 锁模式:eclusive 该行已经被锁定,不允许其它事务锁定。
(转) http://school.cnd8.com/oracle/jiaocheng/33053_3.htm