有多种方法可以接近#1。假设你的要求是正确的(我至少仔细检查过它们,因为它们听起来很奇怪),我可能要做的是创建一个如下所示的ApplicationLock表:
CREATE TABLE ApplicationLock(SessionId UniqueIdentifier,CreateDate DateTime,LockType int,Active bit)
然后,在您想要做某些需要锁定的操作之前,请检查是否存在阻止您执行所需操作的活动锁。 (如果有的话,看看它是否通过了一段定义的超时时间,如果超过了某个超时时间,你应该可以清除该锁。)如果没有锁会阻止你,请插入你自己的锁(你可以用Guid.NewGuid()在Silverlight客户端上创建一个SessionId),做你需要做的事情,然后清除锁定。如果所有这些都可能发生在一个Web服务方法调用中,那么您应该确保将其包装在一个事务中,以便在出现问题时自动回滚该锁。
关键是确保你的锁被清除。如果一个锁只需要一次WCF方法调用,那么你应该可以很容易地在你的服务器端代码中处理它。但是,如果他们需要坚持跨方法调用,我认为您需要一个多部分策略。如果您在WCF服务中使用面向连接的绑定(如Net.TCP),则可以处理客户端断开事件,这将允许您自动清除已打开的任何锁。不过,我不会依赖这个,我会有一些超时作为后备。
对于#2(防止多人在编辑表格时发生冲突),这取决于在业务级别会出现什么样的冲突问题。如果你只是担心插入两个具有相同主键的行,那么有一些简单的方法。假设你有一个代理键作为你的PK,你应该使这个代理键是一个UniqueIdentifier(例如,一个GUID,它允许你在客户端安全地创建键),或者你可以使它成为int/identity column,然后使用SCOPE_IDENTITY()从表中检索值。我更喜欢GUID,但都可以。
如果您需要防止用户编辑可能在其下面发生更改的值,那么您将进入乐观与悲观的锁定状态。这是一个相当复杂的话题,但你可以开始here。
在附注中,我提到需求听起来很奇怪。你至少应该看看各种各样的SQL Transaction Isolation Levels,看看是否设置任何这些会给你你需要的。
嗨,谢谢你的回答。你为什么说这很奇怪?你是怎么意思的? 我假设您在退出应用程序时清除锁定。如果由于某种原因锁不起作用(浏览器崩溃等)会发生什么? – immuner 2010-04-16 13:51:59
有关锁没有被清除的好处 - 我忘了你在这里处理WCF/Silverlight。我编辑了我的答案以反映这一点。 关于“怪异”,我的意思是这样的:当我遇到像你所描述的要求时,我总是试图找出他们的实际商业原因。很多时候,作为“要求”传递给我的是实际上有人试图在“解决方案”的基本要求。一旦你得到了真正的需求,你可能会找到比原先提出的更好的解决方案。 – 2010-04-16 17:45:55
欢呼声我会看看这个。然而你怎么看待q2? 我想我可能没有解释清楚为什么我需要这个(根据需求),所以我会尽力解释更好。 我的应用程序包含一个地图,它允许添加存储在数据库中的点。 模式1适用于任何人都可以使用它来查看地图上的点。这只读取数据库。 模式2允许一些用户(当从管理员启用时)也在地图上添加一个点。这到q2这是重要的解决。 模式3更像是一个迷你cms,它可以更改应用程序的更多数据,这可能会由sessionid解决。 – immuner 2010-04-16 20:24:08