SQL里面什么样的情况才需要用到锁?(大家来 讨论)

zhnzzy 2008-03-24 11:44:14
我记得以前写存储过程一般写成

begin tran
update ....
select.....
commit tran
这样格式就OK了.好像也没遇到并发吗?是应为我数据量小海是怎么回事呢?
是不是数据量操作很大的时候,即表里面同一条数据被频繁使用的时候才需要用到锁呀!
...全文
73 点赞 收藏 14
写回复
14 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
JiangHongTao 2008-03-24
[Quote=引用楼主 zhnzzy 的帖子:]
我记得以前写存储过程一般写成

SQL code
begin tran
update ....
select.....
commit tran

这样格式就OK了.好像也没遇到并发吗?是应为我数据量小海是怎么回事呢?
是不是数据量操作很大的时候,即表里面同一条数据被频繁使用的时候才需要用到锁呀!
[/Quote]
你这样是对的,反过来就错了。
begin tran
select.....
update ....
commit tran
回复
henreash 2008-03-24
关注一下。也在为并发冲突的问题伤脑筋。
不过假如在提交订单前要去判断库存量的时候应该锁一下。如商品A有100个,甲用户需要80个 去看看够用 乙用户需要50个 去看看也够用,那么甲乙同时提交后 商品A库存变成-30了。在判断前就应该将商品A的库存记录锁定
回复
zhnzzy 2008-03-24
[Quote=引用 3 楼 happyflystone 的回复:]
缺省下锁是MSSQL自己管理 的


由系统软件在内部管理,并基于用户所执行的操作被获取和释放。
[/Quote]

那什么情况下缺省模式不好用了?
回复
-狙击手- 2008-03-24
缺省下锁是MSSQL自己管理 的


由系统软件在内部管理,并基于用户所执行的操作被获取和释放。
回复
hui_hui_2007 2008-03-24
多人同时操作时,就是并发。
比如银行取款。当库存金额为1000元时,两个同一时刻取100元。如果不考虑并发的话,库存金额为变成900元。实现应为800元。
回复
dawugui 2008-03-24
有两个或多个人要同时修改一条记录时.
回复
henreash 2008-03-24
update操作的时候自动加上UpdLock,所以在Select前执行Update操作没有问题的,
但是如果先Select在去Update就必须自己加锁了。
否则两个用户都Select到相同的数据,在根据这些数据去Update操作就造成了并发问题
1.(select 我的存款余额 as aa update 我的存款余额=aa-100)
2.(select 我的存款余额 as aa update 我的存款余额=aa-100)
如果1和2同时执行 可能最终只减少100 而不是200
这是要加上行锁: Select 我的存款余额 from Table with (RowLock,HoldLock)
回复
qiyousyc 2008-03-24
哈哈,你的代码有锁的,只是没有造成阻塞而已。
回复
bhujm 2008-03-24
(SET TRANSACTION ISOLATION LEVEL
{ READ COMMITTED
| READ UNCOMMITTED
| REPEATABLE READ | SERIALIZABLE})

READ COMMITTED

指定在读取数据时控制共享锁以避免脏读,但数据可在事务结束前更改,从而产生不可重复读取或

幻像数据。该选项是SQL Server 的默认值。

避免脏读,并在其他session 在事务中不能对已有数据进行修改。共享锁。

READ UNCOMMITTED

执行脏读或 0 级隔离锁定,这表示不发出共享锁,也不接受排它锁。当设置该选项时,可以对数

据执行未提交读或脏读;在事务结束前可以更改数据内的数值,行也可以出现在数据集中或从数据

集消失。该选项的作用与在事务内所有语句中的所有表上设置 NOLOCK 相同。这是四个隔离级别中

限制最小的级别。

REPEATABLE READ

锁定查询中使用的所有数据以防止其他用户更新数据,但是其他用户可以将新的幻像行插入数据

集,且幻像行包括在当前事务的后续读取中。因为并发低于默认隔离级别,所以应只在必要时才使

用该选项。

SERIALIZABLE

在数据集上放置一个范围锁,以防止其他用户在事务完成之前更新数据集或将行插入数据集内。这

是四个隔离级别中限制最大的级别。因为并发级别较低,所以应只在必要时才使用该选项。该选项

的作用与在事务内所有 SELECT 语句中的所有表上设置 HOLDLOCK 相同。

============================
不知道对楼主是否有用?
回复
zhnzzy 2008-03-24
是的,我就是想问问什么情况下系统默认的级别是起不到应有的作用的!
回复
JiangHongTao 2008-03-24
[Quote=引用 8 楼 hui_hui_2007 的回复:]
to6楼,你说的反过来就不对了,什么意思呀?
select 与 update 的位置影响什么?
[/Quote]
你用查询分析器打开两个窗口:
第一个窗口放下面的代码:
create table tb(id int)
insert tb select id = 0
go
begin tran
declare @i int
select @i = max(id)+1 from tb
waitfor delay '00:00:30'
update tb set id = @i
commit tran
select * from tb

第二个窗口放下面的代码:
begin tran
declare @i int
select @i = max(id)+1 from tb
update tb set id = @i
commit tran
select * from tb

先执行第一个窗口的代码,在30秒之内执行第二个窗口的代码,你看看结果是什么。
回复
ojuju10 2008-03-24
数据量比较大,多个用户同时操作时就需要锁定,防止并发
回复
hui_hui_2007 2008-03-24
to6楼,你说的反过来就不对了,什么意思呀?
select 与 update 的位置影响什么?
回复
JiangHongTao 2008-03-24
接6L,如果你还有这样写,又要正确结果,就只好自己加锁进行管理了。
回复
相关推荐
发帖
MS-SQL Server
创建于2007-09-28

3.3w+

社区成员

MS-SQL Server相关内容讨论专区
申请成为版主
帖子事件
创建了帖子
2008-03-24 11:44
社区公告
暂无公告