我有一张这样的表:
CREATE TABLE Tasks(
Name text,
Date datetime
)
在我的申请表中,每个人都会将他/她的任务添加到此表中 每天晚上我的机器人都会选择要完成的第一个任务,因此它会调用Storedprocedure:
CREATE PROCEDURE PickTask
begin
select top (1) * from Tasks
delete top (1) from Tasks
end
机器人将调用PickTask
,直到Tasks
表中没有行。
我的机器人工作多线程,所以我想知道如果我的应用程序中的两个或多个线程想要拨打PickTask
会发生什么?
在第一个我认为select
查询将为两个线程执行,因此两个线程从Tasks
中选择一行,之后每个线程将删除一行,最后机器人执行一次任务两次并删除一个未完成的任务!!
我尝试使用TRANC
,但我不确定,我的应用程序是否有执行任务的问题?
答案 0 :(得分:0)
如果您将其更改为:
CREATE PROCEDURE PickTask
begin transaction
select top (1) * from Tasks
delete top (1) from Tasks
commit
您可以确定无论哪个程序首先调用此程序都会锁定任务,直到完成这两个步骤。然后下一个调用picktask的下一个程序将独占锁定任务。您可能希望将整个事物包装在begin try / begin catch块中。
答案 1 :(得分:0)
您可以在T-SQL中使用应用程序锁定,如以下链接所示:http://www.sqlteam.com/article/application-locks-or-mutexes-in-sql-server-2005
您将在SELECT语句之前获取存储过程中的锁,然后在删除行时立即释放该锁,尽管最好使用使用唯一键的WHERE子句删除该行从SELECT获得,因为SELECT和DELETE之间发生的任何添加(虽然不太可能)都可以删除,但从未被选中。