2

我是 NHibernate 的新手,在为我当前的网站设置它时遇到了困难。该网站将在具有一台数据库服务器的多个网络服务器上运行,这让我面临一些并发问题。该网站将有大约 50.000 名注册用户,每个用户都有一个个人资料页面。在这个页面上,其他用户可以“喜欢”另一个用户,就像 Facebook 一样。这是并发问题的开始。

我正在考虑使用二级缓存,很可能使用 MemChached 提供程序,因为我将拥有多个网络服务器。使用 NHibernate 实现这种“喜欢”功能的最佳方法是什么?我在考虑三个选项:

  1. 使用简单的 Count() 查询。将有一个表'User_Likes',其中每一行代表一个用户对另一个用户的喜欢。要显示喜欢的数量,我会简单地询问用户的喜欢数量,这将被翻译成简单的数据库SELECT COUNT(*) FROM USER_LIKES WHERE ID = x。但是,我认为这会带来很大的性能损失,因为每次用户访问个人资料页面并且喜欢另一个用户时,都必须重新计算喜欢的数量,无论是否二级缓存。
  2. 在用户表中使用附加NumberOfLikes列并在用户喜欢或不喜欢另一个用户时增加/减少此值。然而,这给了我并发问题。使用一个简单的 for 循环,我通过在两台服务器上喜欢一个用户 1000 次来测试它,数据库中的结果总共大约 1100 个喜欢。那是900的差异。无论是不是现实测试,这当然不是一个选择。现在,我将乐观和悲观锁定视为一种解决方案(是吗?)但我目前的存储库模式恐怕不适合使用它,所以在我修复它之前,我想知道如果这是正确的方法。
  3. 像 2,但使用自定义 HQL 并自己编写更新语句,类似于UPDATE User SET NumberOfLikes = NumberOfLikes + 1 WHERE id = x. 这不会给我数据库中的任何并发问题,对吗?但是,由于二级缓存,我不确定我的多台服务器上是否会有任何数据不匹配。

所以......我真的需要一些建议。还有其他选择吗?这感觉像是一种常见的情况,当然 NHibernate 必须以一种优雅的方式支持这一点。我是 NHIbernate 的新手,所以一个清晰、详细的回复是必要的和感激的 :-) 谢谢!

4

2 回答 2

1

我怀疑你会在更多地方看到这个问题。您可以使用 3. 解决此特定问题,但这会留下您将遇到并发问题的其他位置。

我建议的是实现悲观锁定。执行此操作的常用方法是将事务应用于整个 HTTP 请求。在BeginRequest您的 中Global.asax,您开始一个会话和事务。然后,在EndRequest你提交它。对于该Error事件,您可以选择回滚并丢弃会话的替代路径。

这是应用 NHibernate 的一种公认的方式。参见例如http://dotnetslackers.com/articles/aspnet/Configuring-NHibernate-with-ASP-NET.aspx

于 2010-11-22T13:57:58.990 回答
0

I'd go with 3. I believe this in this kind of application it's not so critical if some pages show a slightly outdated value for a while.

IIRC, HQL updates do not invalidate the entity cache entry, so you might have to do it manually.

于 2010-11-23T00:32:39.540 回答