我正在尝试找到处理此异常的完美方法,并强制客户端更改覆盖导致冲突的任何其他更改。我想出的方法是将调用包装到Session.Transaction.Commit()
在循环中,在循环内部,我将执行一个 try-catch 块,并通过复制其属性(行版本属性除外)单独处理每个陈旧对象,然后刷新对象以获取最新的数据库数据,然后将原始值重新复制到刷新的对象,然后进行合并。一旦我循环,我将提交,如果有其他的话StaleObjectStateException
发生,则同样适用。循环不断循环,直到解决所有冲突。
此方法是 UnitOfWork 类的一部分。为了更清楚,我将发布我的代码:
// 'Client-wins' rules, any conflicts found will always cause client changes to
// overwrite anything else.
public void CommitAndRefresh() {
bool saveFailed;
do {
try {
_session.Transaction.Commit();
_session.BeginTransaction();
saveFailed = false;
} catch (StaleObjectStateException ex) {
saveFailed = true;
// Get the staled object with client changes
var staleObject = _session.Get(ex.EntityName, ex.Identifier);
// Extract the row-version property name
IClassMetadata meta = _sessionFactory.GetClassMetadata(ex.EntityName);
string rowVersionPropertyName = meta.PropertyNames[meta.VersionProperty] as string;
// Store all property values from client changes
var propertyValues = new Dictionary<string, object>();
var publicProperties = staleObject.GetType().GetProperties();
foreach (var p in publicProperties) {
if (p.Name != rowVersionPropertyName) {
propertyValues.Add(p.Name, p.GetValue(staleObject, null));
}
}
// Get latest data for staled object from the database
_session.Refresh(staleObject);
// Update the data with the original client changes except for row-version
foreach (var p in publicProperties) {
if (p.Name != rowVersionPropertyName) {
p.SetValue(staleObject, propertyValues[p.Name], null);
}
}
// Merge
_session.Merge(staleObject);
}
} while (saveFailed);
}
上面的代码工作正常,并使用客户端获胜规则处理并发。但是,我想知道 NHibernate 中是否有任何内置功能可以为我执行此操作,或者是否有更好的方法来处理此问题。
提前致谢,
您所描述的是缺乏并发检查。如果不使用并发策略(乐观锁、版本锁或悲观锁),则不会抛出 StaleStateObjectException 并且会发出更新。
好的,现在我了解您的用例了。重要的一点是,抛出异常后应该丢弃 ISession。您可以使用 ISession.Merge 来合并分离的持久对象之间的更改,而不必自己执行此操作。不幸的是,合并不会级联到子对象,因此您仍然需要自己遍历对象图。所以实现看起来像这样:
catch (StaleObjectStateException ex)
{
if (isPowerUser)
{
var newSession = GetSession();
// Merge will automatically get first
newSession.Merge(staleObject);
newSession.Flush();
}
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)