Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1569943
  • 博文数量: 201
  • 博客积分: 2812
  • 博客等级: 少校
  • 技术积分: 3029
  • 用 户 组: 普通用户
  • 注册时间: 2011-01-18 18:28
个人简介

从事数据库工作多年,目前看好分布式NeSQL/HTAP数据库在企业客户市场的发展。未来的主要方向是——致力于 NewSQL/HTAP 数据库的推广普及。

文章存档

2016年(1)

2015年(8)

2014年(23)

2013年(50)

2012年(32)

2011年(87)

分类: Sybase

2013-09-11 20:42:40

     ANSI SQL标准定义了4种隔离级别,用来在并发环境中规定数据库事务对数据所做的改变对于其他事务来说哪些是可见的,哪些是不可见的。事务的隔离级越高,并发能力越差、系统开销越大。因此,在进行应用开发时,在满足需求的前提下,最好使用低隔离级别。    
   SAP Sybase ASE数据库支持ANSI SQL标准定义的全部4种隔离级别,从本文开始将向广大SAP Sybase ASE的初学者介绍事务和并发控制的知识。ASE数据库的事务和并发控制相对来说比较复杂,如果初学者不能正确掌握的话,开发出来的应用系统会遇到很多问题,比容性能和并发能力低等方面的问题。这篇文章将向初学者介绍ANSI SQL定义的4种事务隔离级别,本文近可能以简单的语言描述并结合例子进行介绍。
1. Read Uncommitted(隔离级别1,未提交数据
   事务在这种隔离级别下,允许读取/访问(看到)其他事务中尚未提交的数据修改。读取未提交的数据,也被称之为脏读(Dirty Read)。通常情况下,很少使用这种隔离级别。

2. Read Committed(读取提交数据
   在这种隔离级别下,事务只能访问其他事务已经提交的数据修改。"读提交"隔离级别虽然解决了“脏读”问题,但是可能会遇到"不可重复读"问题:"即一个事务在先后两次执行相同查询语句所读取到的数据值发生了不一致。这是由于在前后两次执行相同语句期间,其它的事务对数据进行了update或delete操作并且已经提交了事务而导致的"。例如:
  事务TA执行如下操作:
    begin transaction
      .....
      select balance from accounts where actno=1234567   --第一次读取
      .....
      select balance from accounts where actno=1234567  --第二次读取
      ....
    commit 
  
   事务TA在第1次执行查询时得到账号123567的余额是1000;当他第2次执行相同查询语句之前,事务TB执行了如下操作序列并提交:
    begin transaction
      ......
      update accounts set balance=balance+100 where actno=1234567
    commit

   这样一来,事务TA第2次执行相同查询时得到账号1234567的余额就是1100了,两次查询结果不一致,即遇到了"不可重复读"问题!此外,如果事务TB执行了delete accounts where actno=1234567,那么事务TA在第2次执行查询时就会找不到对应记录了。

3. Repeatable Read(可重复读)
   在这种隔离级别下,事务可以重复多次执行同一查询,并且读到的结果集中的任何一行记录都不会被其他事务更新或删除。这种隔离级别虽然解决了"不可重复读"问题,但是可能会遇到"幻像读 (Phantom Read)"问题:"即当事务读取满足某一范围条件的数据行时,另一个事务又在该范围内插入了新行,当事务再次读取该范围的数据行时,会发现有新的"幻像" 行"。例如:
   事务TA执行如下操作:
     begin transaction
       .....
       --第一次读取
       select count(*) from accounts where balance>=1000 and balance <=3000 
       .....
       select count(*) from accounts where balance>=1000 and balance <=3000
       ....
     commit 
   事务TA在第1次执行查询时得到账户余额在1000和3000之间的账户数,假设为500;当他第2次执行相同查询语句之前,事务TB执行那个了如下事务并提交:
   begin transaction
     ......
     insert into accounts(actno, balance) values (2222222,2000)
   commit
   这样一来,事务TA第2次执行相同查询时得到账户余额在1000和3000之间的账户数就变为501个了,这样两次查询结果不一致!这种不一致是由于insert语句扎入了满足范围条件的新记录行导致的(注意与"不可重复读"的区别)。

4. Serializable(可串行化)
   "可串行化"是ANSI SQL中定义的最高事务隔离级别。在这种隔离级别下,事务可以重复多次执行相同查询,并且每次都能够得到完全相同的结果。在这种隔离级别下,其他事务不能插入任何将出现在结果集中的记录行,从而可以解决"幻像读"问题(参见前面有关"幻像读"的例子)。





   
阅读(3218) | 评论(1) | 转发(0) |
给主人留下些什么吧!~~