[英]JQuery concurrency issue with a Dictionary in WCF Custom Endpoint Behavior
[英]Concurrency issue with WCF and nHibernate
我們有一個 WCF webservice 處理一些業務實體。 ORM 是 nhibernate 4.0.4、.NET 4.0。 我們使用 IDispatchMessageInspector 在 AfterReceiveRequest 中打開一個會話和一個事務,上下文類是 wcf_operation:
public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
{
if (!CurrentSessionContext.HasBind(this.factory))
{
this.log.Log.Debug("Creating NH Session");
var session = this.factory.OpenSession();
session.FlushMode = FlushMode.Never;
session.BeginTransaction();
CurrentSessionContext.Bind(session);
}
return null;
}
在 BeforeSendReply 中提交事務並關閉會話。 只要一次只有一個調用處理一個特定的實體,這就是有效的。
如果兩個並發 webservice 嘗試更新同一個實體,我會收到一個 nhibernate 異常
NHibernate.HibernateException:非法嘗試將集合與兩個打開的會話相關聯
據我了解,兩個更新在數據庫級別發生沖突,我不明白 nhibernate 在這里的問題。 根據我的理解,兩個調用的兩個會話應該是相互獨立的; 我在這里錯過了什么嗎? 可能是配置?
如上所述,我看到了數據庫的問題; 盡管如此,我還是希望有一個例外,聲稱有關並發更新的內容。 由於網絡服務上的流量增長,我擔心我的會話處理存在普遍問題。
這個問題不是並發問題。 問題是您使用 Sessions 的方式不是它們設計的。
從數據庫加載實體對象時,它屬於加載它的會話。 會話持有它已加載的所有對象的內部映射。 如果您嘗試使此會話與由不同會話加載的對象交互,它將識別該對象不在其內部映射中並拋出異常。
請記住,會話遵循UnitOfWork設計模式。 他們注定是短暫的。 您創建一個會話,從數據庫中讀取,進行更改,然后將會話與所有內存中的對象一起丟棄。
NHibernate 確實提供了一種從會話中分離對象然后將其附加到不同會話的方法,但是這種方法在並發環境中會充滿危險。 相反,我建議您修改您的設計,使共享對象不是 nHibernate 實體,而是對該實體的某種關鍵引用,如果需要,它可以允許任何單獨的會話重新加載它。
如果您覺得某些對象確實應該在 WCF 服務的生命周期內一直保留在內存中,您可以使用 nHibernate 二級緩存。 這個博客條目很好地解釋了二級緩存。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.