1

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

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

Matched
+UserId
+PartnerId

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

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

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

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

4

3 回答 3

1

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

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

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

于 2012-09-04T20:20:11.020 回答
1

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

其他并发问题可以通过使用并发跟踪字段来解决。请参阅在 ASP.NET MVC 应用程序中使用实体框架处理并发

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

于 2012-09-04T19:13:17.380 回答
0

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

于 2012-09-04T19:24:08.760 回答