【问题标题】:Making my matching system thread safe and dealing with concurrency使我的匹配系统线程安全并处理并发
【发布时间】:2012-09-04 18:04:08
【问题描述】:

我正在尝试构建一个实时匹配用户的系统。根据特定标准,用户的匹配是 1 对 1。我有以下数据库表(有点像聊天轮盘赌类型系统):

Pool
+UserId
+Gender
+City
+Solo (bool)

Matched
+UserId
+PartnerId

当用户进入某个页面时,他们被添加到Pool 表中,Solo 设置为 true。然后系统通过查询Pool 表来搜索另一个用户,并返回Solo 为真(意味着他们没有合作伙伴)并且GenderCity 也等于他们查询的结果的结果。如果返回匹配项,则将两个用户都放入Matched 数据库,并将Pool 表中的Solo 列都转换为false。如果它们断开连接,它们将从Matched 表中删除,它们的Solo 列将更改为true。我在尝试构建线程安全和并发的方式时遇到了麻烦。以下是我遇到的一些问题:

-如果两个用户同时查询Pool 数据库并且都返回相同的“solo”用户怎么办?如何防止这种情况发生?

-如果有 1 个用户在用户的 solo 列更改之前查询了 ​​Pool,那么现在该用户在结果集中返回,但从技术上讲,他不是单独的

-我还面临哪些其他并发/线程安全问题?还有比这更好的方法吗?

【问题讨论】:

    标签: c# asp.net asp.net-mvc-3 entity-framework thread-safety


    【解决方案1】:

    解决这个问题的一个非常简单的方法是将您的算法包装在一个事务中,将隔离级别设置为可序列化,并在出现死锁的情况下重试整个业务操作。这应该可以解决您在问题中的所有顾虑。

    在如此复杂的情况下,让您的应用程序能够抵抗死锁并不容易。我了解您刚刚开始使用数据库中的锁定和并发。这个解决方案虽然不完美,但可能就足够了。

    如果您需要更多复杂性,您可能需要围绕悲观锁定进行一些研究。

    【讨论】:

    • 将算法包装在事务中是什么意思?抱歉,我理解你说的如果系统检测到有冲突就重试业务操作是什么意思,但是我不明白你把我的算法包装在一个事务中是什么意思
    • 事务是指数据库事务。 SQL Server 和 EF 支持这些。这意味着您执行的所有查询(包括 DML)都在一定的原子性和隔离性保证下发生。
    【解决方案2】:

    我认为部分问题在于“Solo”字段是多余的;它只是指示“匹配”表中是否存在有效条目。我建议删除它,而只是将“池”表加入“匹配”表,这样您就不必担心保持两者同步的问题。

    其他并发问题可以通过使用并发跟踪字段来解决。见Handling Concurrency with the Entity Framework in an ASP.NET MVC Application

    另外,这只是我的意见,但您可能需要考虑使用“审核”类型的表来保存已删除的条目,或者切换到使用临时表来存储“匹配项”,而不是简单地删除条目。这些信息在未来可能会非常有用,用于调整匹配算法等。

    【讨论】:

    • 仅仅打开一些 EF 选项并不能解决他的特殊挑战。
    • 确实,仅仅添加它是不够的;您还必须添加适当的逻辑来检测冲突,并适当地处理它们(链接说明了如何)。
    【解决方案3】:

    排队是个好主意。如果每个匹配请求都排队,则查询池不会出现争用或死锁。

    【讨论】:

    • lock 是进程级锁。这在 Web 应用程序中是不可取的。该应用应该是无状态的并且可以多实例化。
    猜你喜欢
    • 1970-01-01
    • 2015-09-21
    • 1970-01-01
    • 2020-01-05
    • 2017-12-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多