在阐述数据库事务的隔离级别之前,先来解释一下下面几个重要的概念:脏读,不可重复读,幻读。下面举例说明:
假设一张person表:
id name age
-------------------------------------------------------
1 Tom 12
2 Bob 25
现在同时有两个线程a和b对这张表进行并发访问:
1 脏读: 一个线程读到了另一线程还未提交的数据。如:
a线程发出了一条更新语句:update person set age=21 where id=1,但在它还未提交之时,
b线程发出了一条查询语句:select age from person where id=1,得到的结果是age=21。脏读就这样产生了
2 不可重复读: 一个线程在一个连接中,先后发出2条相同的查询语句得到的结果完全不一样。
产生的原因:另一个线程修改了当前线程正在操作的数据。 如:
a线程发出了一条查询语句:select age from person where id=1,得到的结果是age=12,而在它再次发出这条语句之前,
b线程发出了一条更新语句:update person set age=21 where id=1,并提交了事务。
当a线程再发出相同的查询语句时,得到的结果却是age=21。这就是不可重复读了。
3 幻读: 一个线程在一个连接中,先后发出2条相同的查询语句得到的结果完全不一样。
产生的原因: 另一个线程修改了当前线程正在操作的表中的其它数据,并没有修改它当前操作的数据。 如:
a线程发出了一条查询语句:select age from person where age<22,结果中有一条记录age=12,而在它再次发出这条语
句之前, b线程发出了一条更新语句:update person set age=21 where id=2,并提交了事务。
当a线程再发出相同的查询语句时,得到的结果却是2条记录:age=12和age=21。这就是幻读了
现在该来说说数据库事务的隔离级别了,看看下面这张表就很清楚了:
隔离级别 脏读 不可重复读 幻读
------------------------------------------------------------------------------------------------ 注:Y 代表可能出现,但不一定出现
READ_UNCOMMITED Y Y Y N 代表不可能出现
READ_COMMITTED N Y Y
(Oracle默认)
REPEATABLE_READ N N Y
(Mysql默认)
SERIALIZABLE N N N
解读:
1 解决不可重复读有两种方案:
一、锁定当前操作的数据,禁止对这些数据的同步访问------------悲观锁机制
二、采用版本号机制,允许对同一条数据同步访问,但对数据进行更新都会使其版本号加1---------乐观锁机制
2 解决幻读: 锁定当前操作关联的所有表。但这样效率会很低,一般不会这样做。
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/zxfjava2009/archive/2009/09/06/4524800.aspx