【发布时间】:2015-12-17 18:08:37
【问题描述】:
我需要一个适合有状态应用的 ORM。我将在具有持久客户端连接的低延迟实时游戏服务器中保持请求之间的实体。只有一个服务器实例连接到数据库,因此不能从“外部”更改任何数据,服务器可以依赖其缓存。
当用户远程登录到服务器时,它的整个配置文件被加载到服务器内存中。还为每个用户创建了几个更高级别的服务来操作配置文件数据并提供功能。它们还可以具有内部字段(状态)来存储临时数据。当用户想要更改他的签名时,他要求相应的服务这样做。该服务跟踪用户更改其签名的频率,并且每十分钟仅允许一次(例如) - 数据库中不会跟踪如此短的间隔,这是一种临时状态。此更改应存储到仅执行 1 个查询的 db:UPDATE users SET signature = ... WHERE user_id = ...。当用户注销时,它会在数分钟/数小时不活动后从服务器内存中卸载。这里的db只是一个存储。这就是我所说的有状态。
- 某些实体被认为是“静态数据”,仅在应用程序启动时加载一次。这些可以从其他“动态”实体中引用。加载“动态”实体不应要求重新加载引用的“静态数据”实体。
-
Update/Insert/Delete应该只设置/插入/删除更改的属性/实体,即使是“分离”实体。 - 写入操作不应每次从数据库加载数据(执行
Select)初步检测更改。 (可以在动态生成的继承者中跟踪状态。)我在本地有一个状态,加载任何东西都没有意义。 我想继续跟踪连接范围之外的更改,并在需要时“上传”更改。 - 在执行操作时,不应更改持久对象的引用。
- DBConnection-per-user 无法正常工作。预计在线用户数以千计。
- “静态数据”中的实体可以分配给“动态”实体属性(代表外键),
Update应该正确处理它。
现在我正在使用 NHibernate,尽管它是为无状态应用程序设计的。它支持重新附加到会话,但看起来非常不常见,需要我使用未记录的行为并且不能解决所有问题。
我不确定 Entity Framework - 我可以那样使用它吗?或者你能推荐另一个 ORM 吗?
如果服务器在每次用户点击按钮时重新创建(或特别是重新加载)用户对象,它将非常快速地占用 CPU。 CPU 垂直扩展的成本很高,但影响很小。相反,如果你的 RAM 用完了,你可以去购买更多——比如水平缩放,但更容易编码。如果您认为应该在这里使用另一种方法,我准备讨论它。
【问题讨论】:
-
不知道你为什么说 Nhibernate 是为无状态应用程序设计的。 NH 的会话对我来说似乎很有状态。
-
两种适用架构之间没有太大区别。但是这个问题太宽泛且基于意见,赏金并不能解决这个问题。而且,关于 session.Merge、SaveOrUpdate 等有什么不常见和未记录的?
-
@GertArnold 那些方法使用 Select,见 #3。我必须使用具有一些未记录行为的 Session.Lock(重新附加、执行更改和提交)(当我调用它两次时,它允许我忽略一些检查 - 只有第一次抛出)。
-
情况正好相反。会话设计用于有状态的场景,而不是“在短时间内”使用。当然在 web 等无状态环境中,每个请求绑定一个 session,但是 session 适合桌面场景。换句话说,会话设计并不假定它的用途。
-
@SimonMourier 请参阅stackoverflow.com/questions/3754592/… 最佳答案“请记住,NH 并非旨在与长寿命的 ISession 一起使用”。传递物体也有困难,例如当我有来自一个会话的“静态对象”和来自另一个会话的“动态对象”时。
标签: c# entity-framework nhibernate orm stateful