数据库并发情况下什么情况会出现脏读,如何防范脏读



1
2
3
4
5
6
7
8
9
10
BEGIN  tran
DECLARE  @ name  NVARCHAR(50)
SELECT  @ name = name  FROM  dbo.investor  WITH (UPDLOCK)  WHERE  id=1206
IF @ name = 'sxf359'
BEGIN
UPDATE  dbo.investor  SET  name = 'sxfabc'  WHERE  id=1206
END
PRINT @ name
WAITFOR DELAY  '0:00:20'
COMMIT  TRAN

此事务在执行过程中,如果使用

SELECT * FROM dbo.investor WITH(NOLOCK)  WHERE id=1206

读取该条数据,感觉上name字段应该读取到的是sxf359。我一直是这样认为的,因为事务还没提交,还没更新为sxfabc。但事实是读取到的是sxfabc。把事务未最终提交的数据读取出来了。一些“脏数据”或未被提交的数据潜在的可能被读取,这就是脏读。我对脏读的定义有了更清晰的认识。

若用SELECT * FROM dbo.investor   WHERE id=1206 读取数据,或者SELECT * FROM dbo.investor WITH(UPDLOCK) WHERE id=1206 读取数据,这个时候都会处于等待状态,直到事务执行完毕,才会执行这个两个读取操作

但,如果是下面的事务情况:

1
2
3
4
5
6
7
BEGIN  tran
DECLARE  @ name  NVARCHAR(50)
SELECT  @ name = name  FROM  dbo.investor  WITH (UPDLOCK)  WHERE  id=1206
 
PRINT @ name
WAITFOR DELAY  '0:00:20'
COMMIT  TRAN


下面的这两条语句同时都能够执行:

SELECT * FROM dbo.investor WITH(NOLOCK)  WHERE id=1206

SELECT * FROM dbo.investor   WHERE id=1206


但是,下面这条语句不能执行:

SELECT * FROM dbo.investor WITH(UPDLOCK) WHERE id=1206

这条语句只有在事务执行完毕才会执行。

updlock意思就是更新锁

防范脏读,保险的方法是使用 with(updlock)   ,但通常像这种正常读取SELECT * FROM dbo.investor   WHERE id=1206 就可以了。因为若使用with(updlock)情形下,下步必然是要更新数据​

  • 4
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值