简体   繁体   English

SQL Server 2008 Express锁定

[英]SQL Server 2008 Express locking

OK so I have read a fair amount about SQL Server's locking stuff, but I'm struggling to understand it all. 好的,所以我已经阅读了很多有关SQL Server锁定的内容,但是我正努力理解所有这些内容。

What I want to achieve is thus: 因此,我想要实现的是:

I need to be able to lock a row when user A SELECTs it 我需要能够在用户A SELECT时锁定行

If user B then tries to SELECT it, my winforms .net app needs to set all the controls on the relevant form to be disabled, so the user can't try and update. 如果用户B随后尝试选择它,则我的winforms .net应用程序需要将相关表单上的所有控件都设置为禁用,因此用户无法尝试更新。 Also it would be nice if I could throw up a messagebox for user B, stating that user A is the person that is using that row. 如果我可以为用户B抛出一个消息框,说明用户A是使用该行的人,那也很好。

So basically User B needs to be able to SELECT the data, but when they do so, they should also get a) whether the record is locked and b) who has it locked. 因此,基本上,用户B需要能够选择数据,但是当他们这样做时,他们还应该获得a)记录是否被锁定以及b)谁被锁定。

I know people are gonna say I should just let SQL Server deal with the locking, but I need User B to know that the record is in use as soon as they SELECT it, rather than finding out when they UPDATE - by which time they may have entered data into the form, giving me inconsistency. 我知道人们会说我应该让SQL Server处理锁定,但是我需要用户B在选择记录后立即知道该记录正在使用中,而不是找出何时更新-到那时他们可以在表格中输入了数据,这给我带来了不一致。

Also any locks need to allow SELECTs to still happen - so when user B does his SELECT, rather than just being thrown an exception and receiving no/incomplete data, he should still get the data, and be able to view it, but just not be able to update it. 同样,任何锁都需要允许SELECT仍然发生-因此,当用户B执行其SELECT时,他不仅应该获得数据并能够查看它,而不仅仅是抛出异常并接收不/不完整的数据,而不仅仅是能够更新它。

I'm guessing this is pretty basic stuff, but there's so much terminology involved with SQL Server's locking that I'm not familiar with that it makes reading about it pretty difficult at the moment. 我猜这是很基本的东西,但是SQL Server锁定涉及很多术语,我不熟悉,这使得当前很难阅读。

Thanks 谢谢

To create this type of 'application lock', you may want to use a table called Locks and insert key, userid, and table names into it. 要创建这种类型的“应用程序锁定”,您可能需要使用一个名为Locks的表,并在其中插入键,用户ID和表名。

When your select comes along, join into the Locks table and use the presence of this value to indicate the record is locked. 出现选择时,请加入Locks表并使用此值的存在来表示记录已被锁定。

I would also recommend adding a 'RowVersion' column to your table you wish to protect. 我还建议您在要保护的表中添加“ RowVersion”列。 This field will assist in identifying if you are updating or querying a row that has changed since you last selected it. 此字段将有助于识别您是要更新还是查询自上次选择以来已更改的行。

This isn't really what SQL Server locking is for - ideally you should only be keeping a transaction (and therefore a lock) open for the absolute minimum needed to complete an atomic operation against that database - you certainly shouldn't be holding locks while waiting for user input. 这并不是SQL Server锁定的真正目的-理想情况下,您只应保持事务(以及锁)的打开状态,以完成针对该数据库的原子操作所需的绝对最低限度-您当然不应在保持锁的同时等待用户输入。

You would be better served keeping track of these sorts of locks yourself by (for example) adding a locked bit column to the table in question along with a locked_by varchar column to keep track of who has the row locked. 通过(例如)在表中添加一个locked位列以及一个locked_by varchar列来跟踪谁已锁定行,可以更好地自己跟踪这些类型的锁。

The first user should UPDATE the row to indicate that the row is locked and who has it locked: 第一个用户应UPDATE该行以指示该行已被锁定以及被谁锁定:

UPDATE MyTable 
SET `locked`  = 1
AND `locked_by` = @me
WHERE `locked` = 0

The locked = 0 check is there to protect against potential race conditions and make sure that you don't update a record that someone else has already locked. locked = 0校验用于防止潜在的比赛情况,并确保您不更新别人已经锁定的记录。

This first user then does a SELECT to return the data and ensure that they did really manage to lock the row. 然后,第一个用户执行SELECT来返回数据,并确保他们确实设法锁定了该行。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM