【发布时间】:2010-03-12 19:45:34
【问题描述】:
我设置了一个系统来锁定数据库表中的某些内容,因此一次只有一个用户可以编辑该内容。很简单,那部分工作正常。但是现在我遇到了如何发送请求以“解锁”内容的路障。我有解锁内容的存储过程,但是当用户刚刚关闭浏览器时,我将如何/在哪里调用它?
【问题讨论】:
标签: asp.net database tsql global
我设置了一个系统来锁定数据库表中的某些内容,因此一次只有一个用户可以编辑该内容。很简单,那部分工作正常。但是现在我遇到了如何发送请求以“解锁”内容的路障。我有解锁内容的存储过程,但是当用户刚刚关闭浏览器时,我将如何/在哪里调用它?
【问题讨论】:
标签: asp.net database tsql global
您也不知道用户何时关闭了他的计算机。你必须反过来做。
要求定期更新锁。只有网站会定期更新。如果用户停止使用该网站,则锁定到期。
否则,要求用户明确解锁内容。其他想要编辑内容的用户可以在他们无法完成工作时对第一个用户大喊大叫。不是一个技术解决方案,但仍然是一个很好的解决方案。羞耻有效。
【讨论】:
您真正能做的最好的事情就是在您的 global.asax 中的 Session_End 中添加一些内容。不幸的是,直到会话超时才会触发。
当用户在浏览器中点击“X”时,无论如何都不能保证浏览器会向您发送任何内容。
【讨论】:
关于 Session_End 方法的简要说明。如果你使用这种方法,那么你必须确保
那个会话状态是 InProc,例如。在您的 Web.config 中添加类似的内容
确保您已将 IIS 设置为在正常操作期间不回收工作进程(参见例如 this blog post)。
编辑: 不直接直接回答问题,但另一种方法是对有问题的数据使用Optimistic concurrency control。
【讨论】:
有“用户关闭浏览器”等事件。
不过,我可以想到两种解决方法:
【讨论】:
试图离开 stackoverflow 答案页面会弹出一个“你确定”对话框。也许在 SO 使用的 on-page-leave 事件期间(或者 SO 这样做),您可以使用 XmlHttpRequest 对象发送最终请求。这不会涵盖浏览器进程是否意外关闭(为此使用 session_onend),但它至少会更早发送“我已关闭”事件
【讨论】:
我认为您的一个存储过程可以进行锁定和解锁(与“Select @strNewMax As NewMax”一起使用)...
这是我拥有的系统中的一个示例:
Declare @strNewMax Char
Select @strNewMax = 'N'
BEGIN TRANSACTION
/* Lock only the rows for this Item ID, and hold those locks throughout the transaction. */
If @BidAmount > (Select Max(AB_Bid_AMT) from AuctionBid With(updlock, holdlock) Where AB_AI_ID = @AuctionItemId)
Begin
Insert Into AuctionBid (AB_AI_ID, AB_Bid_AMT, AB_Emp_ID, AB_Entry_DTM)
Select @AuctionItemId, @BidAmount, @EmployeeId, GetDate()
Select @strNewMax = 'Y'
End
COMMIT TRANSACTION
Select @strNewMax As NewMax
这将插入一条记录作为下一个最高出价,同时锁定整个表格,因此不会同时处理其他出价。它将返回“Y”或“N”,具体取决于它是否有效。
也许您可以接受并调整它以适合您的应用程序。
【讨论】: