Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1571607
  • 博文数量: 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-24 15:40:28

      "可串行化"是ANSI SQL中定义的最高事务隔离级别。运行在这种隔离级别下的事务不会发生"脏读"、"不可重复读"以及"幻像读",事务可以重复多次执行相同查询,并且每次都能够得到完全相同的结果。在这种隔离级别下,其它事务不能插入任何将出现在结果集中的记录行。ASE是如何实现的呢,我们结合例子加以说明。让我们看一个例子,假设事务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之间的账户数假设为5;当它第2次执行相同查询语句之前,事务TB执行了如下语句:
    begin transaction
      ......
      insert into accounts(actno, balance) values ('2222222',2000)
    commit

    假设TB执行的insert语句在事务TA第一次查询完成之后,第二次执行开始之前运行;TA和TB都是非链式模式,TA运行在隔离级别3下,TB运行在隔离级别1下,表accounts采用"datarows"锁定机制。
 
    由于事务TA运行在隔离级别3下,当执行头一个select语句时由于balance字段上有可用索引,ASE会对查询命中的(即满足查询条件的)记录行加"共享行级范围锁(range locks)",即"Sh_row range locks";如果没有可用索引的话,ASE会加"共享表级范围锁",即 "Sh_table range lock"。下面分两种情况描述:
   (1) 如果accounts表中已有数据中没有balance> 3000的记录,那么ASE还会加一个"无限键锁(Infinity key lock)",对于本示例就是"Sh_row  Inf  key"锁。当事务TB执行insert语句插入balance=2000的新记录,ASE需要获得排它行锁(Ex_row),由于TA事务持有"Sh_row  Inf  key"锁,因此TB的排它锁请求不能成功,将被阻塞,直到TA事务释放了"Sh_row  Inf  key"锁。这样一来,事务TA第二次执行相同的查询时,得到满足相应条件的账户的个数是与第一次是相一致的,不会产生"幻像读"。
   (2) 如果accounts表中已有数据中具有balance> 3000的记录,那么ASE还会在满足balance>3000的记录集合中选择余额最小的那条记录上也加一个"共享行级范围锁",即"Sh_row range lock",这个锁又叫做"下一键锁(next-key lock)"。当事务TB执行insert语句插入balance=2000的新记录,ASE需要获得排它行锁(Ex_row),由于TA事务持有"next-key lock"锁,因此TB的排它锁请求不能成功,被阻塞,直到TA事务释放了"netxt-key lock锁。这样一来,事务TA第二次执行相同的查询时,得到满足相应条件的账户的个数是与第一次是相一致的,不会产生"幻像读"。

   通过上面的示例,我们可以看到,ASE使用"范围锁"、"无限键锁"或"下一键锁"来防止"幻像读",实现隔离级别3所规定的语义的。
   范围锁可以是共享锁、更新锁或排它锁,根据锁定方案的不同,它们要么是行锁,要么是页锁。对于范围锁,ASE 系统存储过程sp_lock 输出的 context 列中会显示"Range"。对于无限键锁, sp_lock 在不存在的记录行(实际上是根索引页的行 0)上显示一个锁,并在 context 列中显示"Inf key"。

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