想象一下这种情况:
该集合是这样的:
public virtual IList<CustomField> CustomFields { get; protected set; }
我有流利的nhibernate映射,如下所示:
mapping.HasManyToMany(cp => cp.CustomFields)
.AsList(i => i.Column("CustomFieldOrdinal"))
.ParentKeyColumn("RegistrationId")
.ChildKeyColumn("CustomFieldId");
原因是nhibernate正在查询db以获取下一个可用的序数,并且表上没有锁,并且两者都获取了相同的序数。
如何预防?
最佳答案
db中唯一的索引/约束将解决此问题。当然,您将不得不处理两个请求之一的刷新失败。
如果要避免在应用程序端处理异常,则可以改为(此外)对持有列表(ISession.Lock(entity, LockMode.Upgrade)
)的实体发出排他的db锁定,然后再读取(或从db刷新)其列表状态。然后,更新列表。
如果所有插入列表的应用程序都遵循相同的模式,则它们将无法同时插入具有相同索引的元素:它们将等待释放锁,然后将新数据放入db中,然后再读取它并插入自己的新元素。
这是一个pessimistic concurrency pattern。阅读更多here too(此other answer上的链接)。
乐观的人需要使用行版本列,并确保任何列表更新都与实体版本相关。但是,如果是并发,则两个请求之一将有一个并发异常。
关于database - Nhibernate IList(有序列表)竞争条件,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/36604751/