“弹出”记录-在同一语句中选择和删除(SQL Server 2005)

lmn*_*mno 5 c# sql sql-server-2005

我有一个C#应用程序,大约有十几名员工同时使用。它只是从SQL Server 2005表中选择顶部记录,将其删除,然后在表单上显示数据。
一旦选择了记录,就需要将其删除,这样2 ppl不会抓取并在同一条记录上工作。
非常坦率的...

不久前,我发现了一个建议(不能找到我从中得到的网站),在同一条语句中执行SELECT和DELETE并使用此“ compound”语句执行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);
Run Code Online (Sandbox Code Playgroud)

到目前为止,它的运行情况还不错,但是我觉得我很幸运。我们正在招聘大约5个新的员工,我想完全确定这将继续有效。

我很想听听这个地区更多经验丰富的兽医的意见。

我应该坚持“如果它没有坏,不要修复”的方法?还是应该加强我的游戏并使用某种record_locks或存储的proc?

任何建议将被公开接受。如果需要,我可以提供有关表或C#应用程序的更多信息。

Jus*_*ony 2

我建议改用某种乐观并发控制。不要删除记录,而是存储将在选择时抓取的时间戳(或其他版本控制技术)。然后,如果用户编辑某些内容,您可以检查以确保时间戳没有更改。如果有,则提示用户并重新加载新数据。如果没有,则保存数据并更新时间戳,以便其他拥有该数据的人不会覆盖您的更改。

微软关于乐观并发的文章

这是我的图形示例版本(使用编号系统而不是时间戳进行版本控制)

Name|PhoneNum|Version
Joe |123-1234|1
Run Code Online (Sandbox Code Playgroud)
  • UserA 和 UserB 在您的 UI 中提取 Joe 的数据

  • UserA 修改并保存 Joe

现在表格如下所示:

Name|PhoneNum|Version
Joe |555-5555|2
Run Code Online (Sandbox Code Playgroud)
  • UserB 修改 Joe 数据的版本 1 并保存。保存后看到版本现在为2,并提示UserB数据已更改。

更新

如果用户读取该行时无法访问该行,您有两种选择。

代码:

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
Run Code Online (Sandbox Code Playgroud)
  • 您可以添加一个锁定列(使用锁定者的用户 ID),并在选择数据之前更新该列。如果用户崩溃或做了一些没有重置锁的事情,那么您唯一需要担心的就是它。我过去曾使用过这个系统,但如果大多数时候数据都被删除,那么复杂性可能不值得。如果您只需要更新数据,我发现这更有用。您可以添加逻辑,如果同一用户尝试再次获取数据,则让他们这样做,因为这可能是崩溃。否则,您需要创建一个解锁系统。