我有一个C#应用程序,大约有十几名员工同时使用它。它只是从SQL Server 2005表中选择顶级记录,删除它,然后在表单上显示数据 一旦选择了记录,就需要删除它,因此2个人不会抓取并处理相同的记录 相当直接......
我刚才发现了一个建议(无法找到我得到的网站,抱歉)在同一个语句中执行SELECT和DELETE并执行 SqlCommand.ExecuteReader()复合“声明:
SELECT TOP 1 *
FROM Call_Table
WHERE Call_Table.hold_call_till <= GetDate()
ORDER BY Call_Table.attempts ASC, Call_Table.custno ASC;
DELETE
FROM Call_Table
WHERE Call_Table.custno = (SELECT TOP 1 Call_Table.custno
FROM Call_Table
WHERE Call_Table.hold_call_till <= GetDate()
ORDER BY Call_Table.attempts ASC, Call_Table.custno ASC);
到目前为止它一直运作良好,但我觉得我很幸运。我们正在招聘5个新人,我想完全确定这将继续有效。
我很想听听这个领域有更多经验丰富的兽医的意见。
我应该坚持“如果没有破坏,不解决它”的方法?或者我应该加强我的游戏并使用某种record_locks或存储过程?
任何建议都将被公开接受。如有必要,我可以提供有关表或C#应用程序的更多信息。
答案 0 :(得分:2)
我建议使用某种optimistic concurrency control代替。不要删除记录,而是存储将在select上抓取的时间戳(或其他一些版本控制技术)。然后,如果用户编辑了某些内容,您可以检查以确保时间戳没有更改。如果有,则提示用户并重新加载新数据。如果没有,则保存数据,并更新时间戳,以便其他拥有数据的人不会覆盖您的更改。
Microsoft's article on optimistic concurrency
这是我的图形示例版本(使用编号系统而不是版本控制的时间戳)
Name|PhoneNum|Version
Joe |123-1234|1
UserA和UserB在您的用户界面中提取Joe的数据
UserA修改并保存Joe
现在表格如下:
Name|PhoneNum|Version
Joe |555-5555|2
<强>更新强>
如果在用户阅读时无法访问该行,则有两个选项。
代码:
DECLARE @CallInfo TABLE (/*Call_Table Schema*/)
DELETE Call_Table
OUTPUT DELETED.* INTO @CallInfo
WHERE Call_Table.custno = (SELECT TOP 1 Call_Table.custno
FROM Call_Table
WHERE Call_Table.hold_call_till <= GetDate()
ORDER BY Call_Table.attempts ASC, Call_Table.custno ASC)
--The @CallInfo will have the info that you just deleted, so pass that back to the UI
SELECT * FROM @CallInfo
答案 1 :(得分:1)
看起来像你需要的是提示UPDLOCK加上这里描述的READPAST提示 http://www.adathedev.co.uk/2010/03/queue-table-processing-in-sql-server.html
答案 2 :(得分:0)
您可以使用OUTPUT clause的DELETE statement删除行并将其返回到同一语句中,例如:
delete queue output deleted.* where id = (select min(id) from queue)
假设你有一个看起来像这样的表
create table Queue(
ID bigint identity not null primary key,
Data varchar(max)
)