1、在本节课中,你将学到:事务和锁死锁解决,目标,事务可以被定位为一个单一工作单元一起完成的操作,具有原子性(Atomicity )、一致性( Consistency )、隔离性( Isolation)和持久性(Durabilily)原子性:要么所有数据修改被执行要么一个也不执行。一致性:事务在系统完整性中实施一致性,这通过保证任何事务最后都处于有效的状态。如果事务成功地完成,那么系统中所有变化将正确地应用,系统处于有效状态。如果在事务中出现错误,那么系统中的所有变化将自动地回滚,系统返回到原始状态。因为事务开始时系统处于一致状态,所以现在系统仍然处于一致状态。,事务定义,隔离性在隔离状态执行事务
2、,使它们好像是系统在给定时间内执行的唯一操作。如果有两个事务,运行在相同的时间内,执行相同的功能,事务的隔离性将确保每一事务在系统中认为只有该事务在使用系统 。隔离性不仅仅保证多个事务不能同时修改相同数据,而且能够保证事务操作产生的变化直到变化被提交或终止时才能对另一个事务可见,并发的事务彼此之间毫无影响。 事务没有看见中间状态的机会。持久性这说明完成事务对数据产生的改变在系统中保持永久的影响,因此,任何由于事务完成在数据中的改变。,事务定义,事务: 将一组语句作为一个单元执行 必须拥有称为ACID的四个属性 有以下类型: 自动提交事务 显式事务 自动提交事务: 自动提交事务是SQL Serv
3、er的默认事务管理模式 显式事务: 显式事务使用BEGIN TRANSACTION 和 COMMIT TRANSACTION语句指定,创建事务,开始事务Begin transaction 事务名或变量名(变量的值是事务 名,只能为char, varchar, nchar, nvarchar)提交事务Commit transaction事务名或变量名和Commit work标志事务的结束回滚事务RollBack transaction,开始事务,丢失更新 丢失更新发生在多个事务试图修改同一行的时候,事务相互之间不知道对方的存在。那么在事务队列中最后更新的事务覆写前面事务所作的修改。(写后写) 未
4、提交依赖 未提交依赖被称为脏读,事务从表中读取另一个事务未提交的数据(读后写) 不一致分解 事务两次读取数据的过程中,另一个事务对数据成功地进行了改变。(写后读) 幻影读 被称为幻影问题,事务开始在插入语句前面, 幻影读指的是在第二次读取时(当然,SQL语句和第一次的一样),一些新数据被加进来了。导致不能对它进行更新。(读后写),为什么要使用锁,Sql server提供下面两方面的特性;事务管理:确保所有事务的原子性和一致性,事务必须在它们启动之后成功完成,或SQL Server撤销自从事务启动之后的所有的数据修改。锁:保持事务的持久性和隔离性。,Sql server特性,课间思考,下面哪个属
5、性不是事务拥有的? 1. 原子性 2. 一致性 3. 隔离性 4. 分离性,答案: 4. 分离性,事务被回滚: 当事务的执行处于无效状态时 为了维护一致性 使用ROLLBACK TRANSACTION 和ROLLBACK WORK语句回滚事务 语法: ROLLBACK TRANSACTION transaction_name |tran_name_variable |savepoint_name | savepoint_variable,回滚事务,begin tryupdate xiaoset age=35 where xiaoid=3insert xiao values(3,40)commi
6、t transaction tr1select transaction execuatedend trybegin catch rollback transaction tr1select transaction roollbackedend catch,事务,锁: 有助于达到事务完整性 有助于避免: 丢失更新 未提交依赖(脏读) 不一致分解 幻影读 SQL Server 使用下面的锁模式: 共享锁 排他锁 更新锁 意向锁 模式锁 批量更新锁,实现事务完整性,共享 (S) 用于不更改或不更新数据的操作(只读操作),如 SELECT 语句 更新 (U) 用于可更新的资源中。防止当多个会话在读取、
7、锁定以及随后可能进行的资源更新时发生常见形式的死锁。 排它 (X) 用于数据修改操作,例如 INSERT、UPDATE 或 DELETE。确保不会同时同一资源进行多重更新。 意向锁 用于建立锁的层次结构。意向锁的类型为:意向共享 (IS)、意向排它 (IX) 以及与意向排它共享 (SIX)。 架构锁 在执行依赖于表架构的操作时使用。架构锁的类型为:架构修改 (Sch-M) 和架构稳定性 (Sch-S)。,共享锁 共享 (S) 锁允许并发事务读取 (SELECT) 一个资源。资源上存在共享 (S) 锁时,任何其它事务都不能修改数据。一旦已经读取数据,便立即释放资源上的共享 (S) 锁,除非将事务
8、隔离级别设置为可重复读或更高级别,或者在事务生存周期内用锁定提示保留共享 (S) 锁。、 排它锁 排它 (X) 锁可以防止并发事务对资源进行访问。其它事务不能读取或修改排它 (X) 锁锁定的数据。 意向锁 包括意向共享 (IS)、意向排它 (IX) 以及与意向排它共享 (SIX)。,更新锁 更新 (U) 锁可以防止通常形式的死锁。一般更新模式由一个事务组成,此事务读取记录,获取资源(页或行)的共享 (S) 锁,然后修改行,此操作要求锁转换为排它 (X) 锁。如果两个事务获得了资源上的共享模式锁,然后试图同时更新数据,则一个事务尝试将锁转换为排它 (X) 锁。共享模式到排它锁的转换必须等待一段时
9、间,因为一个事务的排它锁与其它事务的共享模式锁不兼容;发生锁等待。第二个事务试图获取排它 (X) 锁以进行更新。由于两个事务都要转换为排它 (X) 锁,并且每个事务都等待另一个事务释放共享模式锁,因此发生死锁。 若要避免这种潜在的死锁问题,请使用更新 (U) 锁。一次只有一个事务可以获得资源的更新 (U) 锁。如果事务修改资源,则更新 (U) 锁转换为排它 (X) 锁。否则,锁转换为共享锁。,独占锁:只允许进行锁定操作的程序使用,其他任何对他的操作均不会被接受。执行数据更新命令时,SQL Server会自动使用独占锁。当对象上有其他锁存在时,无法对其加独占锁。,通过以下隔离等级约束锁: REA
10、D UNCOMMITTED READ COMMITED REPEATABLE READ SNAPSHOT SERIALIZABLE,实现事务完整性(续),read uncommited 隔离级事务可以读取当前事务修改的没有被提交的数据,使用这个隔离级的事务不在数据库对象上放置共享锁,使其它事务修改当前事务读取的对象,数据库对象也没有被排他锁阻塞使得其他事务读取当前事务没有提交的修改过的数据事务可能读取未提交的数据,导致脏读问题 Read commited隔离级不能读取被当前事务修改的数据,防止了脏读问题.这个隔离级在当前事务的每个更新语句上放置排他锁,当这个隔离级被设置的时候,其他事务可以更新
11、事务中个别语句之间的数据.导致幻影读,Repeatable read隔离级事务不能读取当前事务修改的数据, 而且也没有任何其他事务可以更新当前事务内个别语句之间的数据. SNAPSHOT隔离级为每个事务提供了当前数据的快照,每个事务工作并对它们自己复制的数据进行改变,当事务更新变化的时候,它检查数据从它开始使用的数据以来是否被修改并且决定是否更新数据. Seriazable隔离级没有事务可以读取,修改或插入新数据,当数据被事务读取或更新的时.,使用SET TRANSACTION ISOLATION LEVEL语句实现锁 语法: SET TRANSACTION ISOLATION LEVEL R
12、EAD UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SNAPSHOT | SERIALIZABLE ; BEGIN TRANSACTION COMMIT TRANSACTION让我们看看如何,实现事务完整性(续),解决死锁可以通过: 检测死锁 使用更新锁避免死锁,解决死锁,解决死锁:两个或更多事务在隔离的对象上有锁, 并且等待其他对象释放.设置死锁优先级定制死锁超时检测死锁使用更新锁来避免死锁,课间思考,下面哪个并发问题也称为脏读? 1. 未提交依赖 2. 幻影问题 3. 不一致分解,答案: 1. 未提交依赖,课间思考,下面哪个锁允许其他事
13、务浏览当前事务修改的数据? 1. 共享锁 2. 排他锁 3. 更新锁 4. 意向锁 5. 批量更新锁,答案: 1. 共享锁,课间思考,下面哪个锁防止你的数据库死锁? 1. 意向锁 2. 更新锁 3. 共享锁,答案: 2. 更新锁,问题描述: 在AdventureWorks, Inc.中,一个名为Sidney Higa的员工,它当前作为产品技工 WC10被提升为市场经理。Sidney的员工ID是13。作为数据库开发人员,你需要更新他的记录。这包括在员工表中更新职务和更新部门历史表详情。你需要确保所有的改变都生效。而且,你需要确保其他事务应该能够浏览当前事务修改的数据。,演示:实现事务,解决方案:
14、 为了解决上述问题,你需要完成下面的任务: 1. 创建一个事务。 2. 验证输出。,演示:实现事务(续),在本章,你已经学到: 触发器是一块代码,它由一系列T-SQL语句组成,被激活以响应某些动作。 SQL Server支持如下触发器: DML 触发器 DDL 触发器 你可以修改和删除触发器。 事务被用于一起执行一系列语句作为工作的一个逻辑单元。 每个事务包括ACID属性。,小结,SQL Server 支持如下事务: 自动提交事务 显式事务 锁被用于维护事务的完整性。 在没有锁的时候,下面的问题可能发生如果事务被用于同时从数据库中使用相同的数据: 锁更新 未提交依赖 不一致分解 幻影读,小结(续),SQL Server 支持下面的锁模式: 共享锁 排他锁 更新锁 意向锁 模式锁 批量更新锁 死锁是这样一种情况,两个用户(或事务)在两个独立的对象上有锁,并且每个用户想在其他用户的对象上获取一个锁。,小结(续),