2010-08-03 86 views
7

當我們的應用程序(使用NHibernate和ASP.NET MVC)處於壓力測試下時,會引發很多NHibernate事務錯誤。主要種類有:處理NHibernate事務錯誤

  1. 事務未連接,或線路被斷開
  2. 行被另一事務更新或刪除(或者未保存值的映射是不正確的)
  3. 事務(進程ID 177)已被死鎖的鎖定另一個進程的資源,並被選爲死鎖受害者。重新運行交易。

有人可以幫助我找出異常1的原因嗎? 我知道我必須處理我的代碼中的其他異常。有人能指點我的資源,可以幫助我以有效的方式處理這些錯誤嗎?

問:我們如何管理會話和事務?答:我們使用的是Autofac。對於每個服務器請求,我們創建一個新的請求容器,其容器的生命期範圍內有會話。在激活會話時,我們開始交易。當請求完成時,我們提交事務。在某些情況下,交易可能很大。爲了簡化,每個服務器請求都包含在一個事務中。

+0

你如何管理會話和事務? – 2010-08-03 13:05:48

+0

你有沒有找到解決這個問題的方法? – 2010-11-04 16:53:08

回答

1

看一看這個線程: http://n2cms.codeplex.com/Thread/View.aspx?ThreadId=85016

基本上它說什麼,因爲這例外的一個可能的原因:

2010-02-17 21:01:41,204 1警告 NHibernate.Util.ADOExceptio nReporter - System.Data.SqlClient.SqlException: 數據庫 'databasename'的事務日誌已滿。要找出 爲什麼日誌中的空間不能被重用, 看到的log_reuse_wait_desc列 sys.databases中

由於事務日誌的大小是成正比的交易過程中完成的工作量,或許你應該考慮將事務邊界跨越命令處理程序在事務的寫入部分「處理」命令。然後,您將通過#X會話加載您希望進行變異的狀態,對其進行變異並將其提交,這些都是#X中的一個工作單元。

關於事物的讀取方面,您可能會有另一個ISession#Y讀取數據;這個ISession可以用來在例如可重複閱讀或類似的期貨功能,可以簡單地從緩存中讀取(albiet它確實是一個柺杖)。這樣做可能會幫助你從「錯誤」中恢復;活鎖,死鎖和受害者交易。

每個請求使用事務的問題是,您的ISession在您工作時獲取大量的簿記數據,所有這些都是事務的一部分。因此,數據庫將數據(rols,cols,表等)標記爲參與事務,導致等待圖跨越「實體」(在數據庫意義上,而不是DDD意義上),這實際上並不是部分您的應用程序執行的命令的事務邊界。

爲了記錄(其他人使用Google這個),法比奧曾a post處理處理數據層的異常。引用他的一些代碼;

public class MsSqlExceptionConverterExample : ISQLExceptionConverter 
{ 
    public Exception Convert(AdoExceptionContextInfo exInfo) 
    { 
     var sqle = ADOExceptionHelper.ExtractDbException(exInfo.SqlException) as SqlException; 
     if(sqle != null) 
     { 
      switch (sqle.Number) 
      { 
       case 547: 
        return new ConstraintViolationException(exInfo.Message, 
         sqle.InnerException, exInfo.Sql, null); 
       case 208: 
        return new SQLGrammarException(exInfo.Message, 
         sqle.InnerException, exInfo.Sql); 
       case 3960: 
        return new StaleObjectStateException(exInfo.EntityName, exInfo.EntityId); 
      } 
     } 
     return SQLStateConverter.HandledNonSpecificException(exInfo.SqlException, 
      exInfo.Message, exInfo.Sql); 
    } 
} 
  • 547是約束衝突異常號。
  • 208是SQL中無效對象名稱的例外編號。
  • 3960是中止由於更新衝突快照隔離事務的異常號。

所以,如果你正在運行到像你描述的併發問題;記住他們會使你的ISession失效,你必須像上面那樣處理它們。什麼,你可能會尋找

部分是CQRS,那就是你有單獨的讀,寫,兩側。這可能有所幫助:http://abdullin.com/cqrs/,http://cqrsinfo.com

所以總結;您的問題可能與您處理交易的方式有關。另外,請嘗試運行select log_wait_reuse_desc from sys.databases where name='MyDBName',看看它帶給你什麼。

1

這個討論有一個解釋: http://groups.google.com/group/nhusers/browse_thread/thread/7f5fb68a00829d13

總之,數據庫可能是由自身回滾事務,由於一些錯誤,所以,當你嘗試回滾事務後,它已經被回滾和一個殭屍狀態。這往往會隱藏回滾的實際原因,因爲您看到的只是一個TransactionException,而不是實際觸發回滾的異常。

我不認爲有什麼可以做,它超越記錄,並試圖找出是什麼原因造成的潛在錯誤。

0

我知道這篇文章有一段時間了,並假設你修復了它,但似乎你有線程共享問題與NHibernate ISession不是線程安全。基本上1線程正在開始一個事務,另一個線程正試圖關閉它,導致各種混亂。