我目前对为具有版本字段的实体创建映射很感兴趣。但是,我对如何在 Web 环境中使用版本控制感到困惑。在大多数示例中,我看到一个实体在立即发生的 using 语句中更新。
在 Web 示例中,实体在 HTTP GET 中获取,并且在客户端调用 HTTP POST 之前不会更新。我通常在帖子中做的是再次获取实体,更新数据并存储它。但是该实体可能在我的 GET 和 POST 之间发生了变化。我应该在保存之前自己检查版本字段还是有更好的方法?
我目前对为具有版本字段的实体创建映射很感兴趣。但是,我对如何在 Web 环境中使用版本控制感到困惑。在大多数示例中,我看到一个实体在立即发生的 using 语句中更新。
在 Web 示例中,实体在 HTTP GET 中获取,并且在客户端调用 HTTP POST 之前不会更新。我通常在帖子中做的是再次获取实体,更新数据并存储它。但是该实体可能在我的 GET 和 POST 之间发生了变化。我应该在保存之前自己检查版本字段还是有更好的方法?
是的,我认为您需要自己检查一下。您可以这样做的一种方法是,当您在初始获取中检索实体并将其发送回调用方时,在响应中包含版本号。发帖时,请附上版本号。在服务器端,当您重新读取附加的 nHibernate 实体时,从中获取当前版本号。如果您的版本号已过期,请停止更新。
版本 1) 可以手动检查或 2) 依赖于 NHibernate 内置的版本控制功能和 DB 中的时间戳类型。(SQL Server 支持它 - 但很可能其他 DB 也以某种方式做)。在第二种情况下,我们必须处理exception
.
在 NHibernate http://ayende.com/blog/3946/nhibernate-mapping-concurrency中有详细的解释如何处理并发
如果您正在使用 SQL Server,您可以创建列
CREATE TABLE [dbo].[MyTable](
...
[Version] [rowversion] NOT NULL -- new keyword for deprecated [timestamp]
...
然后调整版本映射:
<version name="Version" generated="always" unsaved-value="null" type="BinaryBlob">
<column name="Version" not-null="false" sql-type="timestamp" />
</version>
而且您还应该/需要将版本号传递给客户端并将其绑定到 POST 以及(例如base64
)
每当您尝试使用session.Update(entity)
DB 中较旧的 Version 值时,NHibernate 都会抛出NHibernate.StaleObjectStateException
. 只有在这种情况下,您才能处理它。如果版本匹配,则一切都将正常工作,并且 UPDATE 语句将成功。