锁类型选择的确是sybase数据库设计的一个需要重要考虑的问题!也是sybase开发和管理人员比较头疼的问题,为此,来点关于lock的介绍性资料!
所支持的加锁机制
全页加锁
全页加锁既是一个新术语,它又是由ASE(Adaptive Server Enterprise)在过去所支持的一种加锁类型。这种类型有下列特性:
对所有可被访问的页面在页面级加锁
当各种类型的页面以任何方式发生改变时,对这些排它性的页面进行加锁;而且这种加锁机制一直保持到该事务终止;
当下一个所需的页面已经成功地获得,对那些已经释放的的当前访问页进行共享页面加锁(如果采用了第三层ANSI隔离,则把这种加锁机制保持到该事务终止为止) 采用页级时间印记(timestamp)以确定是否发生改变,详细信息记录在事务日志中,以便在系统恢复时以向前或向后方式使用。
这种加锁方式常常提供性能最高的解决方案,特别是当应用设计时已经考虑了这些特性时更是如此。但是,有一些应用系统,当发生某些活动时,这种对整个页面进行加锁的方式就可能会对系统性能产生有重大意义的影响。对于那些面对诸如文件系统或其它已经支持更细小尺度加锁机制的数据库厂家产品的一般环境而设计的应用系统而言,这种情况尤其如此。
此外,还存在一系列问题,它们要围绕着更加困难的条件进行工作。它们通常要采用更加具有Sybase特性的解决方案。对于商用的应用软件制造厂商而言,对他们是一个挑战,因为这将要求他们必须跨越他们所支持的数据库平台,去完成维护其原代码的工作,而这个工作有相当工作量。在这个领域的基本问题如下:
对已经按照升序值创建的非群聚性索引的最末端叶型页面存在着争议
对非群聚性索引的表进行插入和查询时可能发生死锁;
在按照群聚性的索引值进行更新和对非群聚性索引的表进行查询访问之间可能发生死锁;
在没有作索引的表的最后一行可能发生冲突(尽管对最后的特定地址可以使用分区) ;
有可能使行数很少的表之间发生潜在的冲突(尽管对特定的地址可以使用填充因子[ fillfactors]和每页最大行数[max_rows_per_page]这两个参数)
对每个页面两边进行加锁的需要常常被分割开来;如果一个表特别小,以致在一个单一页面中进行驻留,那么对单一行的访问实际上将破坏对整个表的加锁机制。
仅对数据加锁
仅对数据加锁机制试图去解决本文前一节所关注的主要问题(其他的议题将在其它功能领域中加以解决)。这种加锁方式支持两类不同的工作方式: 数据行加锁和数据页加锁。在这两种情况中,对于它们所支持的加锁方式,都与以前的加锁机制有所不同。仅对数据加锁具有下列特性:
在索引页面中不会破坏事务加锁。相反,而是采用了一种称之为锁存的机制。锁存是一种类似于旋转锁(spinlocks)的同步方法,它们与事务无关并且只保留很短的周期(一般而言,当一个任务在数据库中物理上改变一小片数据时,这个周期相当于在共享存贮区中在一个2K的页面改变某些字节数据的时间)一旦完成之后,这个任务将直接打开这个锁存。当这种情况还可能临时同其它组块时 ,因为这种锁存不能对服务器任务进行有上下文的切换,也不能涉及死锁,并且只能保持主要的一小段时间,所以它们不能产生有显著意义的争用。
采用一个RID对单一行进行数据行加锁(行标识[RID----Row ID]是逻辑页号与所在页面上该行号的组合);
支持固定的行标识 RIDs, 它可以是向前的,允许不进行其RID的改变,就完成数据行的移动。当一行变大超过了它的可用空间时,采用上述结果对非群聚索引不需要进行任何改变。
不需要进行任何争用就可以在表的尾部进行插入操作,这一功能已经增加进来。
支持采用范围加锁、下一个关键字加锁和无限大加锁等方式对逻辑范围值进行加锁
支持由最顶层操作所导致的页面分割。这些情况直接加以提交,"系统"事务可以导致在更短一点的时间周期里保持分裂的页面处于锁定状态。
为了支持这些变化,需要对采用的存贮表结构进行一系列改善。这些改进的主要效果如下:
群聚索引现在被存贮为象许多人所熟悉的IBM DB2产品所采用的“放置索引”("placement indexes.”)方式。这种结构类似于非群聚性的索引,需要类似的空间总量。这种修正的结构导致了在数据初始存贮时可以按照顺序跨数据页进行存储,但是当发生插入时,它们就要尽可能紧密存放以便在正确的逻辑页面中不存在页面分割。此外,在数据页中的数据顺序在新行增加时是不进行维护整理的。这种索引的应用使每个群聚化的索引周游增加了一次I/O操作。
行位移表已经增加到索引页和数据页中。这种增加和新的行索引行存贮格式具有使每个索引页面所存贮的索引条目个数减少的潜在能力。
固定行标识(RIDS)。当一行移动时,对于分配新行位置的向前地址被放在用于驻留该行的位置上。当这种移动需要改变非群聚性索引时,对该行的访问需要增加一次I/O操作以得到‘向前’的位置。
一般而言,索引将更小和更短,这是因为如下原因:
从每个叶级页面中采用双重键限制机制来限制双重键(Duplicate key)例如,如果值“绿”("GREEN”)在下列行标识(RIDs)值等于 123-1,234-2,和345-3的行中, 就分别存贮值“绿”("GREEN”),123-1,234-2,345-3,而不是存贮值“绿” ("GREEN,”)三次。在每个索引页中每个值只存贮一次。
在非群聚性索引树的非叶型结点中将后缀实行压缩(例如,如果键值是"GREEN”和"HAMILTON”,而在这两个值之间发生分裂,那么就在非页级索引页面中存储"G”和"H”)。