资源简介 (共33张PPT)以程序方式处理学生信息管理数据表任务8-1 SQL编程基础目录Contents任务8-2 创建与使用存储过程任务8-3 触发器任务8-4 事务、锁的概念和应用实训 以程序方式处理数据表的数据PART 4任务8-4 事务、锁的概念和应用任务assignments(一)事务概述(二)事务的ACID特性(三)事务的定义(四)事务并发操作的问题(五)事务隔离级别(六)SQL Server的锁定机制(七)活锁和死锁事务、锁的概念和应用任务8-4任务1-1 数据处理【任务分析】为了确保数据的完整性和有效性,可以使用事务确保同时发生的行为与数据的有效性不发生冲突。同时,为了解决并发操作带来的问题,可以使用锁来实现并发控制,以确保多个用户同时操作同一个数据库中的数据时,不会发生数据不一致的问题。【课堂任务】掌握事务和锁的概念及应用。 事务的基本概念及分类 事务的4个属性 并发操作引起的问题 锁的类型 死锁的处理事务、锁的概念和应用任务8-4任务1-1 数据处理(一)事务概述事务就是用户定义的一个数据库操作序列,这些操作要么全做,要么全不做,是一个不可分割的工作单位。事务是单个的工作单元,是数据库中不可再分的基本部分。1.为什么要引入事务事务处理机制在程序开发过程中起着非常重要的作用,它可以使整个系统更加安全。例如,在银行处理转账业务时,如果A账户中的金额刚被转出,而B账户还没有接收就停电;或者A账户中的金额在转出过程中因出现错误未转出,但B账户已完成了转入工作,这会给银行和个人带来很大的经济损失。采用事务处理机制后,一旦在转账过程中发生意外,则整个转账业务将全部撤销,不做任何处理,从而确保数据的一致性和有效性。事务、锁的概念和应用任务8-4任务1-1 数据处理2.SQL Server事务处理机制在数据库中,事务管理不善常常导致用户量很大的系统出现争用和性能问题。随着访问数据的用户数量增加,能够高效地使用事务的应用程序也变得更为重要。SQL Server 数据库引擎使用事务锁定和行版本控制机制,确保每个事务的物理完整性并提供有关应用程序如何高效控制事务的信息。这种控制机制适用从SQL Server 2005 (9.x) 到 SQL Server 2017(除非特别指出)的版本。事务、锁的概念和应用任务8-4任务1-1 数据处理(二)事务的ACID特性事务是作为单个逻辑工作单元执行的一系列操作。一个逻辑工作单元必须有4个特性,即原子性(Atomic)、一致性(Consistency)、隔离性(Isolation)和持久性(Durability),这四个特性总称为ACID特性,只有满足ACID特性才能称为事务。1.原子性一个事务是一个不可分割的工作单元。事务在执行时,应该遵守“要么不做,要么全做(Nothing or All)”的原则,即不允许事务部分地完成,即使因为故障而使事务未能完成,它执行的部分结果就要被取消。保证原子性是数据系统本身的职责,由DBMS的事务管理子系统实现。事务、锁的概念和应用任务8-4任务1-1 数据处理2.一致性事务对数据库的作用是使数据库从一个一致状态转变到另一个一致状态。所谓数据库的一致状态,是指数据库中的数据满足完整性约束。例如,在银行业务中,“从账号A转移资金额R到账号B”是一个典型的事务,这个事务包括两个操作,从账号A中减去资金额R和在账号B中增加资金额R,如果只执行其中的一个操作,则数据库处于不一致状态,账务会出现问题,也就是说,两个操作要么全做,要么全不做,否则就不能成为事务。可见事务的一致性与原子性是密切相关的。确保单个事务的一致性是编写事务的应用程序员的职责,在系统运行中,是由DBMS的完整性子系统实现的。事务、锁的概念和应用任务8-4任务1-1 数据处理3.隔离性如果多个事务并发执行,则应像各个事务独立执行一样,一个事务的执行不能被其他事务干扰,即一个事务内部的操作及使用的数据对并发的其他事务是隔离的。并发控制就是为了保证事务间的隔离性。隔离性是由DBMS的并发控制子系统实现的。4.持久性最后,一个事务一旦提交,它对数据库中数据的改变就应该是持久的。如果提交一个事务以后计算机瘫痪,或数据库因故障受到破坏,那么重新启动计算机后,DBMS也应该能够恢复,该事务的结果将依然是存在的。事务的持久性是由DBMS的恢复管理子系统实现的。事务、锁的概念和应用任务8-4任务1-1 数据处理三)事务的定义一个事务可以是一条SQL语句、一组SQL语句或整个程序,一个应用程序可以包括多个事务。事务的开始与结束可以由用户显式控制。如果用户没有显式地定义事务,则由DBMS按照默认规则自动划分事务。1.开始事务BAGIN TRANSACTION语句标识一个用户自定义事务的开始。此语句可以简化为BEGIN TRAN。事务是可以嵌套的,发布一条BEGIN TRANSACTION命令之后,发布另一个BEGIN TRANSACTION命令,然后提交或回退等待处理的事务。原则上是必须先提交或回退内层事务,然后提交或回退外层事务,即一条COMMIT TRANSACTION或ROLLBACK TRANSACTION语句对应最近的一条BEGIN TRANSACTION语句。事务、锁的概念和应用任务8-4任务1-1 数据处理2.结束事务COMMIT TRANSACTION语句用于结束一个用户定义的事务,保证对数据的修改已经成功地写入数据库。此时事务正常结束。此语句可简化为COMMIT TRAN。3.回滚事务ROLLBACK TRANSACTION取消在当前事务期间所做的任何更改并结束事务。即在事务运行的过程中发生某种故障时,事务不能继续执行,SQL Server 系统将抛弃自最近一条BEGIN TRANSACTION语句以后的所有修改,回滚到事务开始时的状态。4.设置保存点SAVE TRANSACTION语句用于在事务内设置保存点。事务、锁的概念和应用任务8-4任务1-1 数据处理事务、锁的概念和应用任务8-4任务1-1 数据处理(四)事务并发操作引起的问题当同一数据库系统中有多个事务并发运行时,如果不加以适当控制,就可能产生数据不一致性问题。例如,并发取款操作。假设存款余额R=1000元,甲事务T1取走存款100元,乙事务T2取走存款200元,如果正常操作,即甲事务T1执行完毕再执行乙事务T2,存款余额更新后应该是700元,但是如果按照如下顺序操作,则会有不同的结果。(1)甲事务T1读取存款余额R=1000元。(2)乙事务T2读取存款余额R=1000元。(3)甲事务T1取走存款100元,修改存款余额R=R-100=900,把R=900写回到数据库。(4)乙事务T2取走存款200元,修改存款余额R=R-200=800,把R=800写回到数据库。结果两个事务共取走存款300元,数据库中的存款只少了200元。事务、锁的概念和应用任务8-4任务1-1 数据处理得到这种错误的结果是甲、乙两个事务并发操作引起的,数据库的并发操作导致的数据不一致性主要有3种:丢失更新(Lost Update)、脏读(Dirty Read)和不可重复读(Unrepeatable Read)。1.丢失更新当两个事务T1和T2读入同一数据做修改并发执行时,T2把T1或T1把T2的修改结果覆盖了,造成数据丢失更新问题,导致数据不一致。仍以上例中的操作为例进行分析。事务、锁的概念和应用任务8-4任务1-1 数据处理事务、锁的概念和应用任务8-4任务1-1 数据处理2.脏读脏读也称“污读”,即事务T1更新了数据R,事务T2读取了更新后的数据R,事务T1由于某种原因被撤销,修改无效,数据R恢复原值。这样事务T2得到的数据与数据库的内容不一致,这种情况称为脏读。在表8.4中,事务T1把R的值改为900,但此时尚未做COMMIT操作,事务T2将修改过的值900读出来,之后事务T1执行ROLLBACK操作,R的值恢复为1000,而事务T2将仍在使用已被撤销了的R值900。原因在于t4时刻,事务T2读取了T1未提交的更新操作结果,这种值是不稳定的,在事务T1结束前,随时可能执行ROLLBACK操作。事务、锁的概念和应用任务8-4任务1-1 数据处理事务、锁的概念和应用任务8-4任务1-1 数据处理3.不可重复读不可重复读是指一个事务在不同时刻读取同一行数据,但是得到了不同的结果。不可重复读包括以下情况。(1)事务T1读取了数据R,事务T2读取并更新了数据R,当事务T1再读取数据R以进行核对时,得到的两次读取值不一致。(2)事务在操作过程中查询两次,第2次查询的结果包含了第1次查询中未出现的数据或者缺少了第1次查询中出现的数据(这里并不要求两次查询的SQL语句相同)。这种现象称为“幻读(Phantom Reads)。这是因为两次查询过程中有另外一个事务插入或删除了数据。事务、锁的概念和应用任务8-4任务1-1 数据处理事务、锁的概念和应用任务8-4任务1-1 数据处理(五)事务隔离级别在并发操作带来的问题中,“丢失更新”是应该完全避免的。但防止更新丢失,并不能单靠数据库事务控制器来解决,需要应用程序对要更新的数据加必要的锁来解决,因此防止丢失更新应该由应用程序来解决。脏读和“不可重复读”其实都是数据库的一致性问题,必须由数据库提供一定的事务隔离机制来解决。数据库实现事务隔离的方式基本上可以分为两种。(1)在读取数据前,对其加锁,阻止其他事务修改数据。(2)不用加任何锁,通过一定的机制生成一个数据请求时间点的一致性数据快照(Snapshot),并用这个快照来提供一定级别(语句级或事务级)的一致性读取。事务、锁的概念和应用任务8-4任务1-1 数据处理为了解决“隔离”和“并发”的矛盾,SQL-92定义以下4个事务隔离级别。1.未提交读未提交读(Read Uncommitted)是隔离事务的最低级别,该级别允许脏读,但不允许丢失更新。如果一个事务已经开始写数据,则另外一个事务不允许同时进行写操作,但允许其他事务读该行数据。2.已提交读已提交读(Read Committed)级别是SQL Server数据库引擎的默认级别。允许不可重复读,但不允许脏读。读取数据的事务允许其他事务继续访问该行数据,但是未提交的写事务将会禁止其他事务访问该行。事务、锁的概念和应用任务8-4任务1-1 数据处理3.可重复读可重复读(Repeatable Read)级别禁止不可重复读和脏读,但是有时可能出现幻影数据。这可以通过“共享读锁”和“排他写锁”实现。读取数据的事务将会禁止写事务(但允许读事务),写事务则禁止执行任何其他操作。4.可序列化可序列化(Serializable)级别提供严格的事务隔离。它要求事务序列化执行,即事务只能一个接着一个地执行,但不能并发执行。仅仅通过“行级锁定”是无法实现事务序列化的,必须通过其他机制保证新插入的数据不会被刚执行查询操作的事务访问到。事务、锁的概念和应用任务8-4任务1-1 数据处理隔离级别越高,越能保证数据的完整性和一致性,但是对并发性能的影响也越大。对于多数应用程序,可以优先考虑把数据库系统的隔离级别设为已提交读。它能够避免脏读,而且具有较好的并发性能。尽管它会导致不可重复读、幻读和丢失更新这些并发问题,但在可能出现这类问题的个别场合,可以由应用程序采用悲观锁或乐观锁来控制。表8.6列出了4种隔离级别的比较。事务、锁的概念和应用任务8-4任务1-1 数据处理(六)SQL Server的锁定机制SQL Server通过锁来防止数据并发操作过程中引起的问题。锁就是防止其他事务访问指定资源的手段,它是实现并发控制的主要方法,是多个用户能够同时操作同一个数据库中的数据而不发生数据不一致性现象的重要保障。SQL Server提供了多种锁模式,主要包括排他锁、共享锁、更新锁、意向锁、键范围锁、架构锁和大容量更新锁,表8.7所示列出了这些锁模式的说明。事务、锁的概念和应用任务8-4任务1-1 数据处理在SQL Server中使用sys.dm_tran_locks动态管理视图可以返回有关当前活动的锁管理器资源信息,还可以使用系统存储过程sp_lock查看锁的信息。1.使用sys.dm_tran_locks视图在默认情况下,任何一个拥有VIEW SERVER STATE权限的用户均可以查询sys.dm_tran_locks视图。例如,在查询窗口输入下列语句。事务、锁的概念和应用任务8-4任务1-1 数据处理事务、锁的概念和应用任务8-4任务1-1 数据处理Sys.dm_tran_locks视图有两个主要用途。(1)帮助数据库管理员查看服务器上的锁,如果sys.dm_tran_locks视图的输出包含许多状态为WAIT或CONVERT的锁,就应该怀疑存在死锁问题。(2)帮助了解一条SQL语句放置的实际锁,因为用户可能检索一个特定进程的锁事务、锁的概念和应用任务8-4任务1-1 数据处理2.使用系统存储过程sp_lock使用系统存储过程sp_lock可以查看SQL Server系统或指定进程对资源的锁定情况,其语句格式如下。Sp_lock [spid1][, spid2]其中,spid1和spid2为进程标识号。指定spid1、spid2参数时,SQL Server显示这些进程的锁定情况,否则显示整个系统的锁使用情况。进程标识号为一个整数,可以使用系统存储过程sp_who检索当前启动的进程及各进程对应的标识号。事务、锁的概念和应用任务8-4任务1-1 数据处理例如,对department表执行插入和查询操作,检查在程序执行过程中锁的使用情况。USE grademanagerGOBEGIN TRANSACTIONSELECT * FROM departmentEXEC sp_lockINSERT INTO department VALUES('d07', '机电系','张强','209','2222222')SELECT * FROM departmentEXEC sp_lockCOMMIT TRANSACTION执行结果如图8.17所示。事务、锁的概念和应用任务8-4任务1-1 数据处理事务、锁的概念和应用任务8-4任务1-1 数据处理(七)活锁和死锁1.活锁事务T1封锁了数据R,事务T2又请求封锁R,于是T2等待。T3也请求封锁R,T1释放R上的封锁之后,系统首先批准T3的请求,T2仍然等待。然后T4又请求封锁R,T3释放R上的封锁之后,系统又批准了T4的请求,……,T2有可能永远等待,这就是活锁的情形。避免活锁的简单方法是采用先来先服务的策略。2.死锁两个或两个以上的事务分别申请封锁对方已经封锁的数据对象,导致长期等待而无法继续运行下去的现象称为死锁。死锁状态如图8.18所示。事务、锁的概念和应用任务8-4任务1-1 数据处理(1)任务T1具有资源R1的锁(通过从R1指向T1的箭头指示),并请求资源R2的锁(通过从T1指向R2的箭头指示)。(2)任务T2具有资源R2的锁(通过从R2指向T2的箭头指示),并请求资源R1的锁(通过从T2指向R1的箭头指示)。两个用户分别锁定一个资源,之后双方又都在等待对方释放锁定的资源,从而产生一个锁定请求环,出现死锁现象。死锁会造成资源大量浪费,甚至会使系统崩溃。在多用户环境下,数据库系统出现死锁现象是难免的。SQL Server数据库引擎会自动检测SQL Server中的死锁循环,并选择一个会话作为死锁牺牲品,然后终止当前事务(出现错误)来打断死锁。 展开更多...... 收起↑ 资源预览