当前位置: 首页 > news >正文

深圳做网站比较好北京公司网站建设服务

深圳做网站比较好,北京公司网站建设服务,联盟平台,自媒体平台注册头条号事务的隔离级别SQL Server通过在锁资源上使用不同类型的锁来隔离事务。为了开发安全的事务#xff0c;定义事务内容以及应在何种情况下回滚至关重要#xff0c;定义如何以及在多长时间内在事务中保持锁定也同等重要。这由隔离级别决定。应用不同的隔离级别#xff0c;SQL Se… 事务的隔离级别 SQL Server通过在锁资源上使用不同类型的锁来隔离事务。为了开发安全的事务定义事务内容以及应在何种情况下回滚至关重要定义如何以及在多长时间内在事务中保持锁定也同等重要。这由隔离级别决定。应用不同的隔离级别SQL Server赋予开发者一种能力让他们为每一个单独事务定义与其他事务的隔离程度。事务隔离级别的定义如下 是否在读数据的时候使用锁 读锁持续多长时间 在读数据的时候使用何种类型的锁 读操作希望读已经被其他事务排他锁住的数据时怎么办在这种情况下SQL Server可以 一直等到其他事务释放锁 读没有提交的数据 读数据最后提交后的版本 ANSI 99定义了4种事务隔离级别SQL Server 2005能够完全支持这些级别 未提交读 在读数据时不会检查或使用任何锁。因此在这种隔离级别中可能读取到没有提交的数据。 已提交读 只读取提交的数据并等待其他事务释放排他锁。读数据的共享锁在读操作完成后立即释放。已提交读是SQL Server的默认隔离级别。 可重复读 像已提交读级别那样读数据但会保持共享锁直到事务结束。 可序列化 工作方式类似于可重复读。但它不仅会锁定受影响的数据还会锁定这个范围。这就阻止了新数据插入查询所涉及的范围这种情况可以导致幻像读。   此外SQL Server还有两种使用行版本控制来读取数据的事务级别(本章后文将详细检验这些隔离级别)。行版本控制允许一个事务在数据排他锁定后读取数据的最后提交版本。由于不必等待到锁释放就可进行读操作因此查询性能得以大大增强。这两种隔离级别如下 已提交读快照 它是一种提交读级别的新实现。不像一般的提交读级别SQL Server会读取最后提交的版本并因此不必在进行读操作时等待直到锁被释放。这个级别可以替代提交读级别。 快照 这种隔离使用行版本来提供事务级别的读取一致性。这意味着在一个事务中由于读一致性可以通过行版本控制实现因此同样的数据总是可以像在可序列化级别上一样被读取而不必为防止来自其他事务的更改而被锁定。   无论定义什么隔离级别对数据的更改总是通过排他锁来锁定并直到事务结束时才释放。 很多情况下定义正确的隔离级别并不是一个简单的决定。作为一种通用的规则要选择在尽可能短的时间内锁住最少数据但同时依然可以为事务提供它所需的安全程度的隔离级别。 已提交读 在SQL Server 2005中 已提交读隔离级别是建立连接时的默认隔离级别。这个级别存在两种类型已提交读和已提交读快照隔离级别。应用哪种类型由数据库选项定义。已提交读级别会在 读数据之前等待直到阻塞锁被释放。已提交读快照级别会在数据被其他事务阻塞时使用行版本控制来读数据最后一次提交的版本。 使用已提交读级别 BEGIN TRAN   SELECT     FirstName, LastName, EmailAddress FROM     Person.Contact WHERE ContactID 1       返回EmailAddress为[email]gustavo0adventure-works.com[/email]的联系人Gustavo Achong。 现在假设另一事务在事务打开状态下更改了EmailAddress。打开第二个查询窗口并执行以下批来UPDATE EmailAddress但不提交事务 USE AdventureWorks;   BEGIN TRAN UPDATE     Person.Contact SET     EmailAddress [email]uncommittedemail.at[/email] WHERE     ContactID 1     这个UPDATE 语句会正常运行。一行受到了影响即使数据在这个事务还没有运行完之前已被查询窗口1中的事务读取。因为已提交读级别并不会在事务结束前保持用于SELECT语句的共享锁。共享锁会在数据读取之后立即被SQL Server释放。需要一致读的时候这将是一个问题。我们将下面的获取一致的可重复读操作实现。     现在切换到查询窗口1并尝试再次读数据     SELECT         FirstName, LastName, EmailAddress FROM         Person.Contact WHERE         ContactID 1       由于SELECT语句被阻塞因此这个查询并没有结束。SQL Server会尝试在ContactID 1的键上获取一个共享锁但是由于在查询窗口2中的UPDATE语句对其有一个排他锁因此这个操作不可能完成。虽然查询窗口2处于已提交读级别(由于您没有更改默认级别)但排他锁依然存在。这个阻塞将持续存在因为数据更改的排他锁会一直保持直到事务结束。 切换到查询窗口2让查询窗口1中的查询继续运行。键入并执行以下SELECT语句检查数据库中的授权和等待的锁。 可以看一个状态为WAIT的共享锁。这是查询窗口1中运行的查询。它在等待查询窗口2中的查询后者在同样的资源上有一个排他锁。 在查询窗口2中执行一个ROLLBACK TRAN语句来回滚UPDATE语句。然后切换回查询窗口1。可以看到查询窗口1中的查询完成了并且其结果与以前的一样。查询窗口2中的事务结束的时候锁被释放了以至查询窗口1中的查询不再被阻塞。由于查询窗口2中的事务回滚因此查询窗口1中得到的结果是原来的数据。如果查询窗口2中的事务被提交则查询窗口1中会得到新的数据作为结果。 在查询窗口1中执行一个COMMIT TRAN语句并关闭所有的查询窗口。 可以看出在(默认)已提交读级别中SQL Server会 等到排他锁释放之后再进行读操作以此来获取真正的提交数据。还可以看出共享锁会持续到数据被读取之后而排他锁会持续到事务提交之后。在许多事务几乎 同时更改数据的时候这种行为可能会造成问题。在这些情况下由于排他锁造成的阻塞读数据会非常慢。但在有些情况下使用最后提交的数据版本是恰当的。在 这些情况下可以将已提交读级别更改为已提交读快照级别。 如果要在窗口1读取数据的话可以使用这样的方法 SELECT     FirstName, LastName, EmailAddress FROM     Person.Contact WITH (NOLOCK) WHERE     ContactID 1     让它取消所有的锁机制那么排他锁也不会影响到这句查询。     使用NOLOCK注意在 SQL Server 中NOLOCK 提示将启用未提交读行为。在 SQL Server Mobile 中使用 NOLOCK 提示仍会赋予提交读隔离级别。SQL Server Mobile 将维护数据副本以确保可以读取数据而不需要使用共享锁帮助保护数据。 使用已提交读快照级别 激活已提交读快照级别 USE master; ALTER DATABASE AdventureWorks SET READ_COMMITTED_SNAPSHOT ON     注意设置 READ_COMMITTED_SNAPSHOT 选项时数据库中仅允许存在执行 ALTER DATABASE 命令的连接。在 ALTER DATABASE 完成之前数据库中不允许有其他打开的连接。数据库不必处于单用户模式。 现在执行以下代码开始一个事务并像前面一样更改EmailAddress(但要让事务处于打开状态) USE AdventureWorks; BEGIN TRAN UPDATE Person.Contact SET EmailAddress [email]uncommittedemail.at[/email] WHERE ContactID 1; 打开第二个查询窗口并执行以下语句来读取ContactID 1的列Name和EmailAddress列。     USE AdventureWorks; BEGIN TRAN SELECT FirstName, LastName, EmailAddress FROM Person.Contact WHERE ContactID 1; 返回了联系人Gustavo Achong的EmailAddress [email]gustavo0adventure-works.com[/email]这是这一行最后提交的版本。不像没有快照的已提交读级别那样这个查询不会被阻塞。关闭查询窗口2并切换到查询窗口1。 执行以下语句来回滚事务并切换回已提交读级别(这个查询将等待直到关闭查询窗口2) ROLLBACK TRAN GO USE master; ALTER DATABASE AdventureWorks SET READ_COMMITTED_SNAPSHOT OFF 重要提示 这个隔离级别可以用于减少阻塞。但要意识到这是一个数据库选项。当它发生了更改将在数据库系统中使用已提交读级别的所有事务也会改变它们的行为。因此只有在所有这些事务读最后提交的数据版本与读真正提交的数据版本在逻辑上同样正确的时候使用这种级别才是明智的。 获取一致的可重复读操作 已提交读级别的一个缺点是一个事务读取的数据在事务运行期间可能被另一个事务更改。因此在两种已提交读级别下不能保证一致性读。获取一致性读的意思是在一个事务中读取的数据始终是一样的。 1.  已提交读在读数据的时候使用共享锁但在读操作完成后会立即释放这个锁。因此其他事务可以更改刚被读过的数据。 2.  已提交读快照读取最后一次提交的数据版本。当它第二次读数据的时候最后一次提交的版本可能由于第二个事务已经提交了对数据的更改而变成一个新版本。 在需要一致性读的时候(例如对于报表) 可能这种不一致性会导致问题。想象一下您的事务通过数据计算了一些商业数值。在已提交读级别中进行这种计算的时候可能由于基础数据在事务计算过程中发 生了变化而导致这些值被错误计算。为了成功地执行这个计算可以使用快照隔离级别。它会使用行版本管理来提供数据的提交版本但与已提交读快照不同的是 它总会提供在开始事务时最后提交的数据版本。因此SQL Server始终会在整个事务执行过程中获取同样的数据。 使用快照隔离级别     快照隔离级别需要在数据库中一次性地激活。激活之后每个连接可以在需要的时候使用它。     USE master; ALTER DATABASE AdventureWorks SET ALLOW_SNAPSHOT_ISOLATION ON;     现在假设我们希望运行一些基于Sales.SalesOrderDetail表的报表但需要一致性的读操作。执行以下语句为事务激活快照隔离级别并开始一个返回订单行合计的事务。记住OrderTotal的值。 USE AdventureWorks; SET TRANSACTION ISOLATION LEVEL SNAPSHOT BEGIN TRAN SELECT SUM(LineTotal) as OrderTotal FROM Sales.SalesOrderDetail WHERE SalesOrderID 43659 参数SNAPSHOT的含义 1.      指 定事务中任何语句读取的数据都将是在事务开始时便存在的数据的事务上一致的版本。事务只能识别在其开始之前提交的数据修改。在当前事务中执行的语句将看不 到在当前事务开始以后由其他事务所做的数据修改。其效果就好像事务中的语句获得了已提交数据的快照因为该数据在事务开始时就存在。 2.      除非正在恢复数据库否则 SNAPSHOT 事务不会在读取数据时请求锁。读取数据的 SNAPSHOT 事务不会阻止其他事务写入数据。写入数据的事务也不会阻止 SNAPSHOT 事务读取数据。 3.      在数据库恢复的回滚阶段如果尝试读取由其他正在回滚的事务锁定的数据则 SNAPSHOT 事务将请求一个锁。在事务完成回滚之前SNAPSHOT 事务会一直被阻塞。当事务取得授权之后便会立即释放锁。 4.      必须将 ALLOW_SNAPSHOT_ISOLATION 数据库选项设置为 ON才能开始一个使用 SNAPSHOT 隔离级别的事务。如果使用 SNAPSHOT 隔离级别的事务访问多个数据库中的数据则必须在每个数据库中将 ALLOW_SNAPSHOT_ISOLATION 都设置为 ON。 5.      不能将通过其他隔离级别开始的事务设置为 SNAPSHOT 隔离级别否则将导致事务中止。如果一个事务在 SNAPSHOT 隔离级别开始则可以将它更改为另一个隔离级别然后再返回 SNAPSHOT。一个事务从执行 BEGIN TRANSACTION 语句开始。 6.      在 SNAPSHOT 隔离级别下运行的事务可以查看由该事务所做的更改。例如如果事务对表执行 UPDATE然后对同一个表发出 SELECT 语句则修改后的数据将包含在结果集中。     打开第二个查询窗口并更新SalesOrderDetail表以更改查询窗口1中用到的基础数据。(如果希望重复这个示例将OrderQty的值5更改为其他数字以使以下代码能真正地更改数据库中的数据)     USE AdventureWorks; UPDATE Sales.SalesOrderDetail SET OrderQty 5 WHERE SalesOrderID 43659 AND ProductID 777     关闭查询窗口2切换到查询窗口1然后重复下面的SELECT语句。     SELECT SUM(LineTotal) as OrderTotal FROM Sales.SalesOrderDetail WHERE SalesOrderID 43659     可以看出由于快照隔离级别忽略了事务运行过程中数据的更改因此结果与以前的相同。在快照级别下总会提供在事务开始时最后提交的值。 提交这个事务并执行以下代码再次重复这个查询现在可看到由于事务结束了因此结果发生了变化。 COMMIT TRAN SELECT SUM(LineTotal) as OrderTotal FROM Sales.SalesOrderDetail WHERE SalesOrderID 43659     执行以下代码关闭AdventureWorks数据库的快照隔离级别     ALTER DATABASE AdventureWorks SET ALLOW_SNAPSHOT_ISOLATION OFF; 避免同时发生的数据更新 如 前所述快照隔离级别并不在读操作的时候锁定数据但能够在整个事务中提供一致性的视图。在某些情况下有必要在整个事务的执行过程中锁定数据以避免其他 事务对数据的更改。假设希望为一个订单×××。首先需要获取数据并检查它然后为其生成发票。在这种情况下需要从事务起始就锁定数据以避免其他事务更改 它。在这种情况下快照隔离或者已提交读隔离级别都不是好的选择。对于这种情况可以使用可重复读隔离级别。这个隔离级别与没有快照的已提交读级别的工作 过程相似但它会保持共享锁直至事务结束。因此它防止了对数据的更新。 使用可重复读隔离级别     假设希望处理OrderID为43659的订单。首先必须选择数据。为了防止其他事务更改正在读的数据使用可重复读隔离。     USE AdventureWorks; SET TRANSACTION ISOLATION LEVEL REPEATABLE READ BEGIN TRAN SELECT SalesOrderID, SalesOrderDetailID, ProductID, OrderQty FROM Sales.SalesOrderDetail WHERE SalesOrderID 43659     参数REPEATABLE READ的含义 1.  指定语句不能读取已由其他事务修改但尚未提交的行并且指定其他任何事务都不能在当前事务完成之前修改由当前事务读取的数据。 2.  对 事务中的每个语句所读取的全部数据都设置了共享锁并且该共享锁一直保持到事务完成为止。这样可以防止其他事务修改当前事务读取的任何行。其他事务可以插 入与当前事务所发出语句的搜索条件相匹配的新行。如果当前事务随后重试执行该语句它会检索新行从而产生幻读。由于共享锁一直保持到事务结束而不是在 每个语句结束时释放所以并发级别低于默认的 READ COMMITTED 隔离级别。此选项只在必要时使用。 打开第二个查询窗口并执行以下代码尝试更新SalesOrderDetail表以更改查询窗口1中要使用的基础数据     UPDATE Sales.SalesOrderDetail SET OrderQty 5 WHERE SalesOrderID 43659 AND ProductID 777     查询会等待。不像快照隔离级别不可能更新数据因为共享锁会保持以防止其他事务更改数据。这个锁可以通过前面用过的管理视图sys.dm_tran_locks查看。     单击工具条上的取消执行查询按钮取消在查询窗口2中的查询。而执行以下INSERT语句在订单中加入一个新行项。     INSERT INTO Sales.SalesOrderDetail (     SalesOrderID,     CarrierTrackingNumber,     OrderQty,     ProductID,     SpecialOfferID,     UnitPrice,     UnitPriceDiscount ) VALUES(43659,4911-403C-98,1,758,1,874,0)     注意即使正处于可重复读隔离级别这个语句也会成功执行。因为可重复读会锁定数据以阻止数据的更新但INSERT语句向数据库中插入新数据这是允许的。新行处于查询窗口1中事务SELECT语句的查询范围之中所以会在事务下一次获取相同数据的时候被读取到。这称作幻像读。     重复SELECT语句并提交这个事务如下所示     SELECT SalesOrderID, SalesOrderDetailID, ProductID, OrderQty FROM Sales.SalesOrderDetail WHERE SalesOrderID 43659 COMMIT TRAN     可以观察到新行被SELECT语句读取了因为它处于这个语句的查询范围之内。可重复读级别会阻止现有数据被更改但不会阻止新数据插入SELECT语句的查询范围内。 其他     SET TRANSACTION一共有以下几种级别     SET TRANSACTION ISOLATION LEVEL { READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SNAPSHOT | SERIALIZABLE } [ ; ]     上面的例子中没有提到的几种隔离级别的说明 READ UNCOMMITTED 指定语句可以读取已由其他事务修改但尚未提交的行。 在 READ UNCOMMITTED 级别运行的事务不会发出共享锁来防止其他事务修改当前事务读取的数据。READ UNCOMMITTED 事务也不会被排他锁阻塞排他锁会禁止当前事务读取其他事务已修改但尚未提交的行。设置此选项之后可以读取未提交的修改这种读取称为脏读。在事务结束之前可以更改数据中的值行也可以出现在数据集中或从数据集中消失。该选项的作用与在事务内所有 SELECT 语句中的所有表上设置 NOLOCK 相同。这是隔离级别中限制最少的级别。 在 SQL Server 2005 中您还可以使用下列任意一种方法在保护事务不脏读未提交的数据修改的同时尽量减少锁定争用 1.  READ COMMITTED 隔离级别并将 READ_COMMITTED_SNAPSHOT 数据库选项设置为 ON。 2.  SNAPSHOT 隔离级别。 READ COMMITTED 指定语句不能读取已由其他事务修改但尚未提交的数据。这样可以避免脏读。其他事务可以在当前事务的各个语句之间更改数据从而产生不可重复读取和幻像数据。该选项是 SQL Server 的默认设置。 READ COMMITTED 的行为取决于 READ_COMMITTED_SNAPSHOT 数据库选项的设置 1.  如果将 READ_COMMITTED_SNAPSHOT 设置为 OFF默认设置则数据库引擎 会使用共享锁防止其他事务在当前事务执行读取操作期间修改行。共享锁还会阻止语句在其他事务完成之前读取由这些事务修改的行。语句完成后便会释放共享锁。 2.  如果将 READ_COMMITTED_SNAPSHOT 设置为 ON则数据库引擎 会使用行版本控制为每个语句提供一个在事务上一致的数据快照因为该数据在语句开始时就存在。不使用锁来防止其他事务更新数据。 当 READ_COMMITTED_SNAPSHOT 数据库选项设置为 ON 时您可以使用 READCOMMITTEDLOCK 表提示为 READ_COMMITTED 隔离级别上运行的事务中的各语句请求共享锁而不是行版本控制。     注意设置 READ_COMMITTED_SNAPSHOT 选项时数据库中仅允许存在执行 ALTER DATABASE 命令的连接。在 ALTER DATABASE 完成之前数据库中不允许有其他打开的连接。数据库不必处于单用户模式。 SERIALIZABLE 请指定下列内容 1.  语句不能读取已由其他事务修改但尚未提交的数据。 2.  任何其他事务都不能在当前事务完成之前修改由当前事务读取的数据。 3.  在当前事务完成之前其他事务不能使用当前事务中任何语句读取的键值插入新行。 范 围锁处于与事务中执行的每个语句的搜索条件相匹配的键值范围之内。这样可以阻止其他事务更新或插入任何行从而限定当前事务所执行的任何语句。这意味着如 果再次执行事务中的任何语句则这些语句便会读取同一组行。在事务完成之前将一直保持范围锁。这是限制最多的隔离级别因为它锁定了键的整个范围并在事 务完成之前一直保持范围锁。因为并发级别较低所以应只在必要时才使用该选项。该选项的作用与在事务内所有 SELECT 语句中的所有表上设置 HOLDLOCK 相同。 需要注意的地方 1.  一次只能设置一个隔离级别选项而且设置的选项将一直对那个连接始终有效直到显式更改该选项为止。事务中执行的所有读取操作都会在指定的隔离级别的规则下运行除非语句的 FROM 子句中的表提示为表指定了其他锁定行为或版本控制行为。 2.  事务隔离级别定义了可为读取操作获取的锁类型。针对 READ COMMITTED 或 REPEATABLE READ 获取的共享锁通常为行锁尽管当读取引用了页或表中大量的行时行锁可以升级为页锁或表锁。如果某行在被读取之后由事务进行了修改则该事务会获取一个用于保护该行的排他锁并且该排他锁在事务完成之前将一直保持。例如如果 REPEATABLE READ 事务具有用于某行的共享锁并且该事务随后修改了该行则共享行锁便会转换为排他行锁。 3.  在事务进行期间可以随时将事务从一个隔离级别切换到另一个隔离级别但有一种情况例外。即在从任一隔离级别更改到 SNAPSHOT 隔离时不能进行上述操作。否则会导致事务失败并回滚。但是可以将在 SNAPSHOT 隔离中启动的事务更改为任何其他隔离级别。 4.  将事务从一个隔离级别更改为另一个隔离级别之后便会根据新级别的规则对更改后读取的资源执行保护。在更改前读取的资源将继续按照以前级别的规则受到保护。例如如果某个事务从 READ COMMITTED 更改为 SERIALIZABLE则在该事务结束前更改后所获取的共享锁将一直处于保留状态。 5.  如果在存储过程或触发器中发出 SET TRANSACTION ISOLATION LEVEL则当对象返回控制时隔离级别会重设为在调用对象时有效的级别。例如如果在批处理中设置 REPEATABLE READ并且该批处理调用一个将隔离级别设置为 SERIALIZABLE 的存储过程则当该存储过程将控制返回给该批处理时隔离级别就会恢复为 REPEATABLE READ。 转载于:https://blog.51cto.com/xu20cn/66109
http://www.yutouwan.com/news/171202/

相关文章:

  • 太原做淘宝网站的成都市建设局官网
  • 外贸网站做开关的哪个好WordPress手机不显示
  • 学做网站论坛vip教程晋中市科技馆网站建设
  • j建设银行信用卡网站wordpress 插件 破解
  • 做网站价钱怎么查看网站谁做的
  • 周口seo 网站企业网站备案名称窍门
  • 广州黄埔区网站建设m开头的网站开发工具
  • 网站开发好要租服务器吗网页设计图片的边框怎么做
  • 怎样推广自己的产品余姚seo智能优化
  • 海口网站建设流程网站建设預算
  • 海诚网站建设广州网站建设推广
  • 可以做 描文本链接的网站有哪个网站可以学做吃的
  • 如何自建网站入口企业网站的推广形式有
  • 外贸建站与推广做网站加入广告联盟
  • 菜鸟建网站定制网站建设服务商
  • 洛阳网红乐陵seo
  • 厦门做网站优化电子商务市场营销
  • 漳州找人做网站要求哪些wordpress页面点赞
  • txt做网站如何加图片wordpress不能更改邮箱
  • 企业站seo湖南seo网站开发
  • 从化建网站新手做电商卖什么好
  • 西安网站开发定制制作wordpress评论框样式
  • 一流的龙岗网站制作wordpress资源付费
  • 免费wap自助建站火星建站卖农产品最好的平台
  • 中国糕点网页设计网站佛山企业网站建设平台
  • 网站开发哪些专业outlook WordPress设置
  • 自学做网站要多久网站推广行业赚钱吗
  • html5 jsp做网站可以么wordpress和ss一起
  • 论坛网站模板免费下载自己做网站怎么维护
  • 中元建设网站网站开发视频播放无画面