设置隔离级别实现并发控制

13.4.4 设置隔离级别实现并发控制

http://book.51cto.com  2010-02-08 20:03  刘奎  清华大http://new.51c学出版社  我要评论(0)

13.4.4  设置隔离级别实现并发控制

使用隔离级别与通过使用锁定选项控制锁定方式具有相同的效果。通常情况下,使用SET TRANSATION语句来设置事务的隔离级别,该语句的语法格式如下:

  1. SET TRANSATION ISOLATION LEVEL level 

语句中的level表示可选的可隔离级别,从低到高分为READ UNCOMMITTED、REPEATABLE READ和SERIALIZABLE。

下面讲解READ UNCOMMITTED和REPEATABLE READ隔离级别。

1.READ UNCOMMITTED

READ UNCOMMITTED是限制最小的隔离级别。该选项的作用与在事务内所有语句中的所有表上设置NOLOCK相同。当设置该选项时,在事务结束前可以更改数据值。

下面通过实例讲解READ UNCOMMITTED隔离级别的使用方法。

【实例13-8】本实例实现的是用户U1与U2先后访问"商品信息"数据表,并将事务的隔离级别设置为READ UNCOMMITTED。用户U1实现的代码如代码13.9所示;用户U2实现的代码如代码13.10所示。

代码13.9

  1. 01  SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED /* 
    设置事务的隔离级别*/  
  2. 02  BEGIN TRANSACTION  
  3. 03   UPDATE 商品库存 SET 单价 =5.3  
  4. 04   WHERE 名称='豆油'  
  5. 05   PRINT '结束事务前数据表中的数据:'  
  6. 06   SELECT * FROM 商品库存  
  7. 07   WAITFOR DELAY '00:00:15'  
  8. 08   ROLLBACK TRANSACTION  
  9. 09    PRINT '结束事务后数据表中的数据:'  
  10. 10   SELECT * FROM 商品库存 

代码13.10

  1. 11  SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED /* 设置事务的隔离级别*/  
  2. 12   PRINT '读取了用户U1中修改的数据(脏数据)如下'  
  3. 13   SELECT * FROM 商品库存  

【执行代码】首先执行代码13.9,然后执行代码13.10。在U1结束回滚操作之前,U2访问了用户U1正在处理的"商品库存"数据表,因为设置了隔离级别READ UNCOMMITTED,因此出现了读"脏数据"的数据异常。

U1执行以后,输出了U1结束事务之前的数据和结束事务之后的数据,结果如图13.6所示。U2执行以后,读取了用户U1中修改的数据(脏数据),结果如图13.7所示。

 
图13.6  代码13.9的执行结果
 
图13.7  代码13.10的执行结果

【深入学习】关于上述代码的分析如下所示:

第1~2行启动一个事务,在"商品库存"数据表中将事务的隔离级别设置为READ UNCOMMITTED。

第3~6行修改数据表中的数据信息,然后将修改后的数据信息显示出来。

第7~10行在等待15秒之后执行事务回滚的操作,然后将数据表中的数据信息再次显示出来。

第11~13行实现在另一个查询窗口中启动一个事务,在"商品库存"数据表中将事务的隔离级别设置为READ UNCOMMITTED,然后再将数据表中的数据信息显示出来。

说明:若想实现本实例,应首先创建两个不同的查询窗口,然后将代码13.9和代码13.10输入到不同的查询窗口中分别执行,并且两个查询窗口中程序代码的执行间隔不能超过15秒。

2.REPEATABLE READ

使用REPEATABLE READ可以锁定查询中所有的数据,以防止其他用户更改数据。下面通过实例讲解REPEATABLE READ隔离级别的使用方法。

【实例13-9】本实例实现用户U1与U2先后访问"商品库存"数据表,并将事务的隔离级别设置为REPEATABLE READ。用户U1实现的代码如代码13.11所示;用户U2实现的代码如代码13.12所示。

代码13.11

  1. 01  SET TRANSACTION ISOLATION LEVEL REPEATABLE READ /* 设置事务的隔离级别*/  
  2. 02  BEGIN TRANSACTION  
  3. 03   PRINT '数据表中的初始数据值:'  
  4. 04   SELECT * FROM 商品库存  
  5. 05   WAITFOR DELAY '00:00:10'  
  6. 06   PRINT '再次读取数据表中的数据,造成了不重复读取数据'  
  7. 07   SELECT * FROM 商品库存  
  8. 08  ROLLBACK TRANSACTION  

代码13.12

  1. 09  SET TRANSACTION ISOLATION LEVEL REPEATABLE READ /* 设置事务的隔离级别*/  
  2. 10   INSERT INTO 商品库存  
  3. 11   VALUES(12,'大米',300,1.63,'2009-6-2','无')  
  4. 12   PRINT '插入数据后数据表中的数据:'  
  5. 13   SELECT * FROM 商品库存  

【执行代码】首先执行代码13.11,然后执行代码13.12。在用户U1执行第一个SELECT操作和第二个SELECT操作之前,用户U2向数据表中插入了数据,所以造成了用户U1两次查询结果不一致现象的发生。代码13.11执行后的结果如图13.8所示,代码13.12执行后的结果如图13.9所示。

 
图13.8  代码13.11的执行结果
 
图13.9  代码13.12的执行结果

【深入学习】关于上述代码的分析如下所示:

第1~2行启动一个事务,在"商品库存"数据表中将事务的隔离级别设置为REPEATABLE READ。

第3~4行查询"商品库存"数据表中的数据信息。

第5~7行实现在等待10秒之后再次查询"商品库存"数据表中的数据信息的操作。

第8行实现执行事务回滚的操作。

第9~13行实现在另一个查询窗口中启动一个事务,在"商品库存"数据表中将事务的隔离级别设置为REPEATABLE READ,然后向数据表中插入一条数据信息,最后将数据表中的数据信息显示出来。

说明:与前面讲解的相关实例一样,在实现本实例时,应首先创建两个不同的查询窗口,然后将代码13.11和代码13.12输入到不同的查询窗口中分别执行,并且两个查询窗口中程序代码的执行间隔不能超过10秒。

posted @ 2010-03-19 11:01  binfire005  阅读(446)  评论(0编辑  收藏  举报