簡體   English   中英

WCF 和 nHibernate 的並發問題

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM