笔记42-徐 锁产生的背景

笔记42-徐 锁产生的背景

 1 --锁产生的背景
 2 --事务是关系型数据库的一个基础概念。他是作为单个逻辑工作单元执行的一系列操作
 3 --一个逻辑工作单元必须有4个属性,称为原子性,一致性,隔离性,持久性(ACID)
 4 --只有这样才能成为一个事务
 5 
 6 --原子性
 7 --事务必须是原子工作单元;对于其数据修改,要么全都执行,要么全都不执行。
 8 --比如一个事务要修改100条记录,要不就100条都修改,要不就都不修改。不能
 9 --发生只修改了其中50条,而另外50条没有改的情况
10 
11 --一致性
12 --事务在完成时,必须使所有的数据都保持一致状态。在相关数据库中,所有规则都必须
13 --应用于事务的修改,以保持所有数据的完整性。事务结束时,所有的内部数据结构
14 --(如B树索引或双向链表)都必须是正确的
15 
16 
17 --隔离性
18 --由并发事务所做的修改必须与任何其他并发事务所做的修改隔离。事务识别数据所处的状态,
19 --要么是另一并发事务修改他之前的状态,要么是第二个事务修改他之后的状态,事务不会
20 --识别中间状态的数据。也就是说,虽然用户是在并发操作,但是,事务是串行执行的。
21 --对同一个数据对象的操作,事务读写修改是有先后顺序的。不是同一时间什么事情都能同时
22 --做的
23 
24 --持久性
25 --事务完成之后,他对于系统的影响是永久性的。哪怕SQL发生了异常终止,机器掉电,只要
26 --数据库文件还是完好的,事务做的修改必须还全部存在
27 
28 
29 
30 --以上事务的定义对所有的关系型数据库都成立,不管是SQLSERVER,还是DB2,ORACLE,都要
31 --遵从这些限制。但是,不同的数据库系统在事务的实现机制上有所不同,索引产生的效果在
32 --细节上是有差异的。尤其是SQLSERVER和ORACLE,在事务的实现上有很大不同。两者在不同的
33 --应用场景上各有优劣,不好讲谁做得更好,谁做得更差。下面讲的是SQLSERVER实现事务
34 --的方法
35 
36 --要实现业务逻辑上的ACID,有两方面任务
37 
38 --1、数据库程序员要负责启动和结束事务,确定一个事务的范围
39 --程序员要定义数据修改的顺序,将组织的业务规则用TSQL语句表现出来,然后将这些语句包括到
40 --一个事务中。换句话说,数据库程序员负责在必要并且合适的时间开启一个事务,将要做的操作
41 --以正确的顺序提交给SQLSERVER,然后在合适的时间结束这个事务
42 
43 --2、SQLSERVER数据库引擎强制该事务的物理完整性
44 --数据库引擎有能力提供一种机制,保证每个逻辑事务的物理完整性
45 --SQLSERVER通过下面方法做到:
46 
47 --(1)锁定资源,使事务保持隔离
48 --SQLSERVER通过在访问不同资源时需要申请不同类型锁的方式,实现了不同事务之间的隔离。
49 --如果两个事务会互相影响,那么在其中一个事务申请到了锁以后,另外一个事务就必须等待,
50 --直到前一个事务做完为止
51 
52 --(2)先写入日志方式,保证事务的持久性
53 --SQLSERVER通过先写入日志的方式,保证所有提交了的事务在硬盘上的日志文件里都有记录。
54 --即使服务器硬件,操作系统或数据库引擎实例自身出现故障,该实例也可以在重新启动时使用
55 --事务日志,将所有未完成的事务自动地回滚到系统出现故障的点,使得数据库进入一个从事务
56 --逻辑上来讲一致的状态
57 
58 
59 --(3)事务管理特性,强制保证事务的原子性和一致性
60 --事务启动后,就必须成功完成,否则数据库引擎实例将撤销该事务启动之后对数据所做的所有
61 --修改
62 
63 --如果一个连接没有提交事务,SQL会保持这个事务一直在活动状态,并且不在意这个事务
64 --的长短或这个连接是否还在活动,直到这个连接自己提交事务,或登出(logout)SQLSERVER
65 --如果在登出的时候还有未提交的事务,SQL会把这个事务范围内所做的所有操作撤销(回滚)
66 
67 --所以,锁是SQL实现事务隔离的一部分,阻塞正是事务隔离的体现。要实现事务的隔离,阻塞
68 --不是SQLSERVER自找的,而是事务对SQLSERVER提出的要求,也是用户使用事务要付出的代价
69 --一个数据库开发者和DBA的工作,不是去消除阻塞,而是要把阻塞的时间和范围控制在一个
70 --合理的范围之内,使最终用户既能享受事务的ACID,又能享受预期的性能。完全消除阻塞,
71 --是不可能的事情
72 
73 
74 --换句话说,阻塞是实现事务的隔离所带来的不可避免的代价。为了达到良好的性能,数据库
75 --开发者和DBA要把阻塞的时间和范围控制在一个合理的范围之内。这不是一件很简单的工作,
76 --所以阻塞也将会是SQLSERVER的永恒的话题之一。做同样的事情,怎麽才能比较不容易产生
77 --大范围的阻塞呢?
78 
79 --从下面3个方面着手
80 --1、申请资源的互斥度
81 --如果不同的连接申请的锁都是相互兼容的,那么他们就不会产生阻塞
82 
83 --2、锁的范围和数目的多少
84 --做同样一件事情,SQLSERVER申请的锁的粒度和数目可能会不一样。一个良好设计的程序
85 --可以使申请的锁的粒度和数目控制在最小的范围之内。这样,阻塞住别人的可能性就能
86 --大大降低
87 
88 --3、事务持有锁资源的时间长短
89 --如果一个锁是大家都需要用的,那么每个人持有他的时间越短,阻塞对性能的影响就会越小。
90 --最好是申请得越晚越好,释放得越早越好
91 
92 --为了达到以上3个目的,需要研究一下SQLSERVER的锁资源模式和兼容性,以及他们怎麽被
93 --申请和释放的

 

posted @ 2013-07-27 16:15  桦仔  阅读(462)  评论(0编辑  收藏  举报