【问题标题】:How to prevent multiple users from adding an item to a Sharepoint list simultaneously如何防止多个用户同时将项目添加到 Sharepoint 列表
【发布时间】:2011-11-17 09:31:53
【问题描述】:

我正在使用一个简单的表单来让人们注册一个活动。他们的详细信息保存在 Sharepoint 列表中。我有一个可以报名参加活动的人数(比如 100 人)。

如何防止第100和第101人同时注册,导致配额检查允许第101人注册(因为第100人还没有在列表中)?

【问题讨论】:

  • 你说的因为第100个人还没有在列表中并发添加项目是什么意思?第 100 人在 11:54:00 开始流程,并在 11:54:49 提交表单;人 101 在 11:54:30 并在 11:54:48 提交表格;谁应该注册?
  • 个人 101 应该可以注册。第 100 个人应该会收到通知。
  • 您真的遇到过这个问题吗?你不试图过早地解决一个不存在的问题吗?尝试同时注册一个活动的最大用户数是多少?

标签: algorithm sharepoint mutex


【解决方案1】:

ItemAdding 代码放在lock statement 中,以确保一次只有一个线程可以进入代码的关键部分:

private Object _lock = new Object();

public override void ItemAdding(SPItemEventProperties properties)
{
    lock(_lock)
    {
        // check number of the list items and cancel the event if necessary
    }
}

我想出了一个针对具有多个 WFE 的场的解决方案的想法 - 在将项目添加到列表期间,共享资源(上面伪代码中的表中的一行)被锁定:

private Object _lock = new Object();

public override void ItemAdding(SPItemEventProperties properties)
{
    try
    {
        // 1. begin a SQL Server transaction
        // 2. UPDATE dbo.SEMAPHORE
        //    SET STATUS = 'Busy'
        //    WHERE PROCESS = 'EventSignup'

        lock(_lock)
        {
            // 3. check number of the list items and cancel the event if necessary
        }
    }
    finally
    {
        // 4. UPDATE dbo.SEMAPHORE
        //    SET STATUS = ''
        //    WHERE PROCESS = 'EventSignup'
        // 5. commit a SQL Server transaction
    }
}

我离开了lock 语句,因为我不确定如果同一个前端服务器尝试添加项目#100 和#101 会发生什么 - 事务会锁定行还是不会因为相同将使用到 SQL Server 的连接?

【讨论】:

  • 这不一定适用于有多个 WFE 的农场(不过,您说的是一组相当特殊的情况来实现这一点,希望他们不是在运行票务管理员或一些超高容量的网站! )
  • @Ryan 我不确定为什么 OP 如此害怕 添加项目的并发。用户在做什么?坐在一起倒数? 3...2...1...点击!即使他们这样做,我仍然认为这个问题是不可能的。
  • 当然它不太可能(因此 +1)但我想我还是应该提到它。
  • @Ryan 我刚刚更新了我的答案,但不要将第二个代码 sn-p 视为完整的解决方案。这只是我想讨论的一个想法。它有机会工作吗?我们在这里试图解决的一般问题的名称是什么?是distributed semaphore吗?
【解决方案2】:

那么你可以使用事件接收器项目添加方法。在添加项目时,您的项目没有创建,您可以计算当前注册人数。如果大于 100,您可以取消添加项目。

但可以肯定的是,可以触发多个项目添加方法,以防止您计算当前人数并增加计数 +1,并将该值保留在其他地方(可能在事件项目的字段上)和所有项目添加方法都可以在添加项目之前检查该值。

添加项目的方法对于这些操作来说太迟了。

这将是我将使用的解决方案。

【讨论】:

  • 问题是当两个不同的人试图同时注册时同时触发项目添加。他们俩的人数都是99,他们都可以注册。
  • 这就是为什么我说将计数值保留在其他地方,您将匹配项目的计数和您在其他地方持有的值。它不可能像毫秒那样同时发生,使用这种方法,即使是几毫秒也可以节省您的时间。
【解决方案3】:

我猜如果您要更新列,比如说“注册计数”,那么其中一个用户将遇到保存冲突问题。第一次更新值的人获胜,第二次更新失败。

问候, 尼丁·拉斯托吉

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-05
    • 1970-01-01
    • 1970-01-01
    • 2015-12-20
    • 2021-07-11
    相关资源
    最近更新 更多