NHibernate - 具有并发和第二级缓存的计数器 [英] NHibernate - counters with concurrency and second-level-caching

查看:202
本文介绍了NHibernate - 具有并发和第二级缓存的计数器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是新的NHibernate,我有困难设置为我当前的网站。此网站将在多个网络服务器上使用一个数据库服务器运行,这使我面临一些并发性问题。
网站将有大约50.000个用户注册,每个用户将有一个个人资料页面。在这个页面上,其他用户可以喜欢另一个用户,很像Facebook。这是并发问题。

I'm new to NHibernate and am having difficulties setting it up for my current website. This website will run on multiple webservers with one database server, and this leaves me facing some concurrency issues. The website will have an estimated 50.000 users or so registered, and each user will have a profile page. On this page, other users can 'like' another user, much like Facebook. This is were the concurrency problem kicks in.

我想使用二级缓存,最有可能使用MemChached提供程序,因为我会有多个网络服务器。什么是使用NHibernate实现这样的Like功能的最佳方式?我在想三个选项:

I was thinking of using second-level cache, most likely using the MemChached provider since I'll have multiple webservers. What is the best way to implement such a 'Like' feature using NHibernate? I was thinking of three options:


  1. 使用一个简单的Count()查询。将有一个表'User_Likes',其中每一行将表示从一个用户到另一个用户。要显示喜欢数量的数量,我只是问一个用户的喜欢数量,这将被转换为一个简单的数据库 SELECT COUNT(*)FROM USER_LIKES WHERE ID = x 或某事。但是,我认为这将带来极大的性能损失,因为每当用户访问个人资料页面,喜欢另一个用户,喜欢的数量将不得不重新计算,二级缓存或不。

  2. 在用户表中使用另一个 NumberOfLikes 列,并在用户喜欢或不喜欢另一个用户时递增/递减此值。然而这给了我并发问题。使用一个简单的for循环,我测试它喜欢一个用户在两个服务器上1000次,结果在db是大约1100喜欢总。这是一个差异900.无论是否现实测试,这当然不是一个选择。现在,我看着乐观和悲观的锁定作为解决方案(是吗?),但我目前的Repository模式,目前,不适合使用这恐怕,所以在我修复之前,我想知道这是否是正确的方式。

  3. 像2,但使用自定义HQL和自己写更新语句,沿着 UPDATE User SET NumberOfLikes = NumberOfLikes + 1 WHERE id = x 。这不会给我在数据库的任何并发问题吗?但是,由于第二级缓存,我不确定是否会在我的多个服务器上有任何数据不匹配。

  1. Use a simple Count() query. There will be a table 'User_Likes' where each row would represent a like from one user to another. To display the number the number of likes, I would simply ask the number of Likes for a user, which would be translated to the database as a simple SELECT COUNT(*) FROM USER_LIKES WHERE ID = x or something. However, I gather this would be come with a great performance penalty as everytime a user would visit a profile page and like another user, the number of likes would have to be recalculated, second-level cache or not.
  2. Use an additional NumberOfLikes column in the User table and increment / decrement this value when a user likes or dislikes another user. This however gives me concurrency issues. Using a simple for-loop, I tested it by liking a user 1000 times on two servers and the result in the db was around 1100 likes total. That's a difference of 900. Whether a realistic test or not, this is of course not an option. Now, I looked at optimistic and pessimistic locking as a solution (is it?) but my current Repository pattern is, at the moment, not suited to use this I'm afraid, so before I fix that, I'd like to know if this is the right way to go.
  3. Like 2, but using custom HQL and write the update statement myself, something along the lines of UPDATE User SET NumberOfLikes = NumberOfLikes + 1 WHERE id = x. This won't give me any concurrency issues in the database right? However, I'm not sure if I'll have any datamismatch on my multiple servers due to the second level caching.

我真的需要一些建议。还有另一个选择吗?这感觉像一个常见的情况,肯定NHibernate必须支持这个优雅的方式。
我是NHIbernate的新用户,所以清楚,详细的回复是必要和赞赏:-)谢谢!

So... I really need some advice here. Is there another option? This feels like a common situation and surely NHibernate must support this in an elegant manner. I'm new to NHIbernate so a clear, detailed reply is both necessary and appreciated :-) Thanks!

推荐答案

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

I suspect you will see this issue in more locations. You could solve this specific issue with 3., but that leaves other locations where you're going to encounter concurrency issues.

我建议是实现悲观锁。通常的做法是只对整个HTTP请求应用一个事务。使用 Global.asax 中的 BeginRequest ,您可以启动会话和事务。然后,在 EndRequest 中提交它。使用错误事件,您可以执行回滚和放弃会话的替代路径。

What I would advise is to implement pessimistic locking. The usual way to do this is to just apply a transaction to the entire HTTP request. With the BeginRequest in your Global.asax, you start a session and transaction. Then, in the EndRequest you commit it. With the Error event, you go the alternative path of doing a rollback and discarding the session.

一个接受的方式应用NHibernate。请参见 http://dotnetslackers.com/articles/aspnet/配置NHibernate-with-ASP-NET.aspx

This is quite an accepted manner of applying NHibernate. See for example http://dotnetslackers.com/articles/aspnet/Configuring-NHibernate-with-ASP-NET.aspx.

这篇关于NHibernate - 具有并发和第二级缓存的计数器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆