数据库事务和锁

使用事务的考虑

在使用事务时,原则上应该使事务尽可能得短并且要避免事务嵌套。事务应该尽可能得短,这是因为比较长的事务增加了事务占用数据的时间,使其它必须等待访问该事务锁定数据的事务,延长了等待访问数据的时间。在使用事务时,为了使事务尽可能得短,应该采取一些相应的方法。为了最小化时间,在使用一些Transact-SQL语句时,一定要非常小心。例如,当使用循环语句WHILE时,一定要事先确认循环的长度和占用的时间,使这种循环在完成相应的功能之前,一定要确保循环尽可能得短。在开始事务之前,一定要了解需要用户交互式操作才能得到的信息。这样,在事务的进行过程中,就可以避免进行一些耗费时间的交互式操作,缩短事务进程的时间。在一个用户定义的事务中,应该尽可能地使用一些数据操纵语言,例如INSERT、UPDATE和DELETE语句,因为这些语句主要是操纵数据库中的数据。而对于一些数据定义语言,应该尽可能地少用或者不用,因为这些数据定义语言的操作既占用比较长的时间,又占用比较多的资源,并且这些数据定义语言的操作通常不涉及到数据,所以应该在事务中尽可能地少用或者不用这些操作。另外,在使用数据操纵语言时,要注意,一定要在这些语句中使用条件判断语句,使得这些数据操纵语言涉及到尽可能少的记录,从而缩短事务的处理时间。

在嵌套事务时,也要注意一些问题。虽然说,在事务中间嵌套事务是可能的,并不影响SQL Server处理事务的性能。但是,实际上,使用嵌套事务,除了把事务搞得更加复杂之外,并没有这么明显的好处。因此,不建议使用嵌套事务。

事务的类型

根据系统的设置,可以把事务分成两种类型。一种是系统提供的事务,另一种是用户定义的事务。系统提供的事务是指在执行某些语句时,一条语句就是一个事务。这时要明确,一条语句的对象既可能是表中的一行数据,也可能是表中的多行数据,甚至是表中的全部数据。因此,只有一条语句构成的事务也可能包含了多行数据的处理。例如执行下面这条数据操纵语句:

UPDATE  authors

SET state = ‘CA’

这是一条语句,这条语句本身就构成了一个事务。这条语句由于没有使用条件限制,那么这条语句就是修改表中的全部数据。所以这个事务的对象,就是修改表中的全部数据。如果authors表中有1000行数据,那么这1000行数据的修改要么全部成功,要么全部失败。

另外一种事务,是用户明确定义的事务。在实际应用中,大多数的事务处理就是采用了用户定义的事务来处理。在开发应用程序时,可以使用BEGIN TRANSACTION语句来定义明确的用户定义的事务。在使用用户定义的事务时,一定要注意两点:一是事务必须有明确的结束语句来结束。如果不使用明确的结束语句来结束,那么系统可能把从事务开始到用户关闭连接之间的全部操作都作为一个事务来对待。事务的明确结束可以使用这样两个语句中的一个:COMMIT语句和ROLLBACK语句。COMMIT语句是提交语句,将全部完成的语句明确地提交到数据库中。ROLLBACK语句是取消语句,该语句将事务的操作全部取消,即表示事务操作失败。

还有一种特殊的用户定义的事务,这就是分布式事务。前面提到的事务都是在一个服务器上的操作,其保证的数据完整性和一致性是指一个服务器上的完整性和一致性。但是,如果一个比较复杂的环境,可能有多台服务器,那么要保证在多服务器环境中事务的完整性和一致性,就必须定义一个分布式事务。在这个分布式事务中,所有的操作都可以涉及对多个服务器的操作,当这些操作都成功时,那么所有这些操作都提交到相应服务器的数据库中,如果这些操作中有一条操作失败,那么这个分布式事务中的全部操作都被取消。

锁和锁的作用

锁就是防止其他事务访问指定的资源的手段。锁是实现并发控制的主要方法,是多个用户能够同时操纵同一个数据库中的数据而不发生数据不一致现象的重要保障。一般来说,锁可以防止脏读、不可重复读和幻觉读。脏读就是指当一个事务正在访问数据,并且对数据进行了修改,而这种修改还没有提交到数据库中,这时,另外一个事务也访问这个数据,然后使用了这个数据。因为这个数据是还没有提交的数据,那么另外一个事务读到的这个数据是脏数据,依据脏数据所做的操作可能是不正确的。不可重复读是指在一个事务内,多次读同一数据。在这个事务还没有结束时,另外一个事务也访问该同一数据。那么,在第一个事务中的两次读数据之间,由于第二个事务的修改,那么第一个事务两次读到的的数据可能是不一样的。这样就发生了在一个事务内两次读到的数据是不一样的,因此称为是不可重复读。幻觉读是指当事务不是独立执行时发生的一种现象,例如第一个事务对一个表中的数据进行了修改,这种修改涉及到表中的全部数据行。同时,第二个事务也修改这个表中的数据,这种修改是向表中插入一行新数据。那么,以后就会发生操作第一个事务的用户发现表中还有没有修改的数据行,就好象发生了幻觉一样


死锁问题

死锁是一个很重要的话题。在事务和锁的使用过程中,死锁是一个不可避免的现象。在两种情况下,可以发生死锁。第一种情况是,当两个事务分别锁定了两个单独的对象,这时每一个事务都要求在另外一个事务锁定的对象上获得一个锁,因此每一个事务都必须等待另外一个事务释放占有的锁,这时,就发生了死锁。这种死锁是最典型的死锁形式。在同一时间内有两个事务A和B,事务A有两个操作:锁定表part和请求访问表supplier;事务B也有两个操作:锁定表supplier和请求访问表part。结果,事务A和事务B之间发生了死锁,其示意进程如图10所示。

 


图10   死锁示意图

死锁的第二种情况是,当在一个数据库中时,有若干个长时间运行的事务执行并行的操作,当查询分析器处理一种非常复杂的查询例如连接查询时,那么由于不能控制处理的顺序,有可能发生死锁现象。

当发生死锁现象时,系统可以自动检测到,然后通过自动取消其中一个事务来结束死锁。在发生死锁的两个事务中,根据事务处理时间的长短作为规则来确定他们的优先级。处理时间长的事务具有较高的优先级,处理时间较短的事务具有较低的优先级。在发生冲突时,保留优先级高的事务,取消优先级低的事务。

会话级锁和表级锁

一般地,锁是由系统自动提供的。但是,在有些情况下,用户也可以定制锁。也就是说,用户可以对会话级锁和表级锁进行定制。

会话级锁的定制包括两个方面,事务孤立等级和锁超时限制。事务孤立等级保护指定的事务,该事务孤立等级允许对一个会话中的全部事务设置孤立等级。当设置孤立等级时,就为会话中的全部语句指定了默认的锁定行为。在指定事务孤立等级时,使用到下面一些选项。READ COMMITTED选项指导系统在读取数据时,使用共享锁。在这种选项下,不能体会到脏读,即不能看到正在修改的数据。但是,在事务结束之前,可以改变数据,所以可以产生不可重复读数据或者幻觉数据。READ UNCOMMITTED选项指导系统既不使用共享锁,也不使用排它锁。在这种选项下,可以看到正在修改的数据,体会到脏读。这个选项是限制程度最低的设置。REPEATABLE READ选项指导系统在查询使用的全部数据上放置锁,防止其他用户修改数据,但是幻觉读可以发生。SERIALIZABLE选项指导系统在数据上放置锁,直到事务完成以后,用户才可以修改或者插入数据。这个选项是限制程度最高的设置。另外,事务等待访问的时间也可以定制,这需要设置锁超时限制。当设置了锁超时时间以后,如果事务等待的时间超过了锁超时时间,那么该事务被自动取消。

定制表级锁就是指通过为表指定一个或者多个选项,设置表级锁的行为。实际上,定制表级锁,就是使用一种优化隐藏的方式。优化隐藏就是指在FROM子句后面,附加上有关的内容选项,提高系统识辨操作的能力。定制表级锁有许多选项。ROWLOCK选项指导系统使用行级锁而不是页级锁或者表级锁,这是系统的默认选项。PAGLOCK选项指导系统使用页级锁。TABLOCK选项指导系统使用表级锁而不是使用锁定对象更细的行级锁或者页级锁,并且使用共享锁,因此允许其他事务读取表中的数据,但是不能修改表中的数据。TABLOCKX选项指导系统使用排它锁,防止其他事务读取或者修改表中的任何数据。NOLOCK选项指导系统不使用锁,既不使用共享锁,也不使用排它锁。在这种情况下,可以体会到脏读。HOLDLOCK选项指导系统占有共享锁直到该事务的结束,而不是当有其他锁请求时立即释放。UPDLOCK选项指导事务在读取表中的数据时,使用修改的页级锁代替共享锁。这个锁一直占用到该语句或者事务的结束为止。

结论

    网络技术是信息技术发展的趋势。多用户、多事务、可伸缩、复制、数据仓库等等都是为了适应网络技术的数据库发展方向。事务作为一个重要的数据库技术的基本概念,在保护数据库的可恢复性和多用户、多事务方面具有基础性的作用。一个事务就是一个单元的工作,该事务可能包括一条语句,也可能包括一百条语句,而这些语句的所有操作,要么都完成,要么都取消。在数据库备份和恢复过程中,事务也具有重要作用,可以利用日志进行事务日志备份、增量备份,而不必每一次都执行耗费时间、精力和备份介质的完全备份。锁是实现多用户、多事务等并发处理方式的手段。锁的类型和资源有多种。锁是由系统自动提供的,用户也可以进行一些定制。在SQL Server 7.0中,一个明显的特征是使用了行级锁。使用行级锁引起了数据存储引擎、事务管理方式等方面的变化

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值