使用Sqlserver更新锁防止数据脏读

有时候我们需要控制某条记录在程序读取后就不再进行更新,直到事务执行完释放后才可以。这时候我们就可以将所有要操作当前记录的查询加上更新锁,以防止查询后被其它事务修改。这种操作只锁定表中某行而不会锁定整个表,体验更好。

  测试sql代码如下:

  在一个查询中执行如下语句

begin tran
 SELECT InvestState FROM InvestOrdersABC WITH (UPDLOCK) where id=10005
 waitfor delay ‘00:00:10‘
 update InvestOrdersABC set InvestState=‘2‘ where id=10005
commit tran

  1、在另外的一个查询中执行以下语句

SELECT InvestState FROM InvestOrdersABC  where id=10005

  发现在第一个事务执行完以前查到的数值还是原来的数值0,直到更新完成后才会变成2,如果加上锁,代码如下:

SELECT InvestState FROM InvestOrdersABC WITH (UPDLOCK) where id=10005

  发现sql语句必须等到第一个连接里的事务完成才执行完成,这是因为这个sql的连接的更新锁认为第一个事务里的更新锁可能会对数据进行修改,因此必须等事务执行完成才执行。此时更新锁变为排他锁。

  2、如果执行更新操作:

begin tran
 update InvestOrders set InvestState=‘3‘ where id=10005
commit tran

  发现无法更改,只能等到第一个查询完成后才会进行修改。其实和加锁不加锁已经没什么关系,为什么呢?因为SQL Server在执行INSERT、 UPDATE 或DELETE 命令时,会自动使用独占锁。

  3、上文的事务未加隔离级别,事务的默认隔离级别为READ  committed,不加锁因此在第1点里还可以进行查询。当数据库事务的隔离级别为REPEATABLE READ,SERIALIZABLE时,如果查询需要加共享锁:

SELECT InvestState FROM InvestOrdersABC WITH (HoldLOCK) where id=10005
时间: 2024-10-18 18:38:13

使用Sqlserver更新锁防止数据脏读的相关文章

SqlServer中的更新锁(UPDLOCK)

优点: 允许读取数据(不阻塞其它事务)并在以后更新数据,同时确保自从上次读取数据后数据没有被更改 当用UPDLOCK来读取记录时可以对取到的记录加上更新锁,从而加上锁的记录在其它的线程中是不能更改的只能等本线程的事务结束后才能更改 begin transelect * from address WITH (UPDLOCK) where [Name]='Z'waitfor delay '00:00:10' update address set [Name]='ZZ'commit tran 注意:

SqlServer——事务—锁与隔离级别

隔离实际上是通过锁来实现的,作用于整个事务,它通常在事务开始前指定,如 SET TRANSACTION ISOLATION LEVEL READ Committed,指定后面的事务为 已提交读:而锁是在我们执行某一具体的SQL语句时在from中指定锁模式来实现的,它可以覆盖掉已指定隔离级别下应用的锁类型.隔离级别牺牲并发性来实现一致性. 并发:是指在相同的时间,多个用户访问相同的数据.它通常引起以下问题:脏读:丢失更新:不可重复度:幻读: 脏读:一个进程读取了另一个进程尚未提交的数据. 不可重复

sql server中的锁 事务锁 更新锁 保持锁 共享锁 你知道吗?

锁定数据库的一个表 SELECT * FROM table WITH (HOLDLOCK) 注意: 锁定数据库的一个表的区别 SELECT * FROM table WITH (HOLDLOCK) 其他事务可以读取表,但不能更新删除 SELECT * FROM table WITH (TABLOCKX) 其他事务不能读取表,更新和删除 SELECT 语句中"加锁选项"的功能说明 SQL Server提供了强大而完备的锁机制来帮助实现数据库系统的并发性和高性能.用户既能使用SQL Ser

SqlServer——事务—锁和隔离的总结

锁定提示对SQL语句进行特别指定,这个指定将覆盖事务的隔离级别.下面对各个锁定提示分别予以介绍(更多资料请查看SQLserver的联机帮助),笔者做出了以下分类. ④     UPDLOCK:发出更新锁,保持到事务事务结束.(更新锁:不阻塞别的事物,允许别的事物读数据(即更新锁可与共享锁兼容),但他确保自上次读取数据后数据没有被更新) 在很多系统中,经常会遇到这种情况,要保持一个编号的唯一,如会计软件中的凭证的编号.一种编号的处理是这样的,把表中的最大编号保存到表中,然后在这个编号上累加,形成新

sqlserver锁机制详解(sqlserver查看锁)

简介 在SQL Server中,每一个查询都会找到最短路径实现自己的目标.如果数据库只接受一个连接一次只执行一个查询.那么查询当然是要多快好省的完成工作.但对于 大多数数据库来说是需要同时处理多个查询的.这些查询并不会像绅士那样排队等待执行,而是会找最短的路径执行.因此,就像十字路口需要一个红绿灯那 样,SQL Server也需要一个红绿灯来告诉查询:什么时候走,什么时候不可以走.这个红绿灯就是锁. 图1.查询可不会像绅士们那样按照次序进行排队 为什么需要锁 在开始谈锁之前,首先要简单了解一下事

初步了解更新锁(U)与排它锁(X)

?? 一直没有认真了解UPDATE操作的锁.近期在MSDN论坛上看到一个问题,询问堆表更新的死锁问题,问题非常easy,有相似这种表及数据: CREATE TABLE dbo.tb( c1 int, c2 char(10), c3 varchar(10) ); GO DECLARE @id int; SET @id = 0; WHILE @id <5 BEGIN; SET @id = @id + 1; INSERT dbo.tb VALUES( @id, 'b' + RIGHT(10000 +

解剖SQLSERVER 第二篇 对数据页面头进行逆向(译)

解剖SQLSERVER 第二篇  对数据页面头进行逆向(译) http://improve.dk/reverse-engineering-sql-server-page-headers/ 在开发OrcaMDF 的时候第一个挑战就是解析数据页面头部,我们知道数据页面分两部分,96字节的页面头部和8096字节的数据行 大神 Paul Randal 写了一篇文章很好的描述了页头结构,然而,即使文章描述得很详细,但是我还是找不出任何关于页头存储的格式 每一个字段的数据类型和他们的顺序 我们可以使用DBC

在SQL Server里为什么我们需要更新锁

今天我想讲解一个特别的问题,在我每次讲解SQL Server里的锁和阻塞(Locking & Blocking)都会碰到的问题:在SQL Server里,为什么我们需要更新锁?在我们讲解具体需要的原因前,首先我想给你介绍下当更新锁(Update(U)Lock)获得时,根据它的兼容性锁本身是如何应对的. 一般来说,当执行UPDATE语句时,SQL Server会用到更新锁(Update Lock).如果你查看对应的执行计划,你会看到它包含3个部分 读取数据 计算新值 写入数据 在查询计划的第1部分

lock(3)——更新锁(U)与排它锁(X)

以下文章中详细介绍了update操作过程中更新锁及排它锁的分配情况 http://blog.csdn.net/zjcxc/article/details/27351779 按照以上文章中的追踪方式,发现其实文章lock(2)——创建及更新表过程中SQL SERVER锁资源分配情况中我们通过sys.dm_tran_locks动态视图查询出来的结果都是最终加锁的情况,并没有体现其中锁变化的情况.如果要想详细的知道锁的变化情况,还是使用profile的方式. 我这里为了加深印象与理解,就再将邹大师的测