日期:2014-05-18  浏览次数:20596 次

sqlserver ******锁*******,对一个表显式加解锁问题
背景:

一个表,本来是标值量函数生成ID(规则+自增的编号)作为主键(其他信息用户决定),
这样只能一条一条地插入数据,没有问题


问题:

现需要一次插入多条数据,放在存储过程中实现,这样,我用标值量函数获取一个ID(用一个变量@temp保存),
作为主键,插入该条信息
然后第二条数据在前一个ID(变量@temp)的基础上+1作为主键,插入该条信息,依次循环

问题就出在你第二个ID的取法上,假如存储过程执行期间,有其他用户对该表执行插入操作,
你之前插入的那条数据放在存过过程中,存储过程开事物,在事物没有提交(完成本次插入数据操作)之前,
别的用户去ID的话,调用标值量函数,标值量函数从这个表中取一个最大的ID+1返回,这时不就出现生成的ID重复了,问题就在这里

所以我想这个存储过程执行期间,在第一个ID生成后(调用标值量函数后),就把这个锁定,任何用户不允许读&&写本表数据
但是不知道可行性,书上说sqlserver的锁机制不用用户显式地去控制,觉得对于常规的读写没问题,复杂一点的业务还是要去控制的,


锁机制的知识掌握的不多,希望sql版的前辈们指点,给出点资源学习也行

谢谢



------解决方案--------------------
锁一个表的某一行
SET TRANSACTION ISOLATION LEVEL REPEATABLE READ
begin tran
select * from tablename with (rowlock) where id=xxx
xxxx
commit tran


------解决方案--------------------
用触发器吧
 如何实现自编号
http://blog.csdn.net/roy_88/article/details/1424370
最好用单号记数据,一次要取多少,一次可以计算和生成,再分配
------解决方案--------------------
对于每个后续 Transact-SQL 语句,SQL Server 将所有共享锁一直保持到事务结束为止。
------解决方案--------------------
insert的时候 系统会自动加共享锁

为了控制并发带来的问题,可以加行锁。
------解决方案--------------------
如果你没有修改隔离级别的话 默认应该为读已提交