在联机事务处理(OLTP)的数据库应用系统中,多用户、多任务的并发性是系统最重要的技术指标之一。为了提升并发性,目前大部分RDBMS都采用加锁技术。然而因为现实环境的复杂性,使用加锁技术又不可避免地产生了死锁问题。所以如何合理有效地使用加锁技术,最小化死锁是开发联机事务处理系统的关键。
1、死锁产生的缘由
在联机事务处理系统中,形成死机主要有两方面缘由。一方面,因为多用户、多任务的并发性和事务的完整性要求,当多个事务处理对多个资源同时访问时,若双方已锁定一部分资源但也都须要对方已锁定的资源时,没法在有限的时间内彻底得到所需的资源,就会处于无限的等待状态,从而形成其对资源需求的死锁。
另外一方面,数据库自己加锁机制的实现方法不一样,各数据库系统也会产生其特殊的死锁状况。如在Sybase SQL Server 11中,最小锁为2K一页的加锁方法,而非行级锁。若是某张表的记录数少且记录的长度较短(即记录密度高,如应用系统中的系统配置表或系统参数表就属于此类表),被访问的频率高,就容易在该页上产生死锁。
2、容易发生死锁的几种状况以下:
一、不一样的存储过程、触发器、动态SQL语句段按照不一样的顺序同时访问多张表;
二、在交换期间添加记录频繁的表,但在该表上使用了非群集索引(non-clustered);
三、表中的记录少,且单条记录较短,被访问的频率较高;
四、整张表被访问的频率高(如代码对照表的查询等)。
3、以上死锁状况的对应解决方案
数据库
一、在系统实现时应规定全部存储过程、触发器、动态SQL语句段中,对多张表的操做老是使用同一顺序。如:并发
有两个存储过程proc一、proc2,都须要访问三张表zltab、z2tab和z3tab,若是proc1按照zltab、z2tab和z3tab的顺序进行访问,那么,proc2也应该按照以上顺序访问这三张表。 高并发
二、对在交换期间添加记录频繁的表,使用群集索引(clustered),以减小多个用户添加记录到该表的最后一页上,在表尾产生热点,形成死锁。这类表多为往来帐的流水表,其特色是在交换期间须要在表尾追加大量的记录,而且对已添加的记录不作或较少作删除操做。 spa
三、对单张表中记录数不太多,且在交换期间select或updata较频繁的表可以使用设置每页最大行的办法,减小数据在表中存放的密度,模拟行级锁,减小在该表上死锁状况的发生。这类表多为信息繁杂且记录条数少的表。如:索引
系统配置表或系统参数表。在定义该表时添加以下语句: with max_rows_per_page=1 事务
四、在存储过程、触发器、动态SQL语句段中,若对某些整张表select操做较频繁,则可能在该表上与其余访问该表的用户产生死锁。对于检查帐号是否存在, 但被检查的字段在检查期间不会被更新等非关键语句,能够采用在select命令中使用at isolation read uncommitted子句的方法解决。该方法实际上下降了select语句对整张表的锁级别,提升了其余用户对该表操做的并发性。在系统高负荷运行时,该方法的效果尤其显著。 资源
如:select * from titles at isolation read uncommitted 开发
对流水号一类的顺序数生成器字段,能够先执行updata流水号字段+1,而后再执行select获取流水号的方法进行操做。it