2011-03-20 78 views
3

我遇到了一個問題,使用TransactionScope時事務不回滾。我們在內存SQLite數據庫中使用NHibernate,這樣在應用程序整個生命週期(在這種情況下,一些單元測試)期間,我們僅限於一個數據庫連接。TransactionScope與SQLite內存中的數據庫和NHibernate

using (var ts = new TransactionScope(TransactionScopeOption.Required, 
            TimeSpan.Zero)) 
{ 
    using (var transaction = _repository.BeginTransaction()) 
    { 
     _repository.Save(entity); 
     transaction.Commit(); 
    } 
    // ts.Complete(); <- commented Complete call still commits transaction 
} 

即使我刪除了NHibernate的內部嵌套事務,所以代碼如下所示,事務仍然被提交。

using (var ts = new TransactionScope(TransactionScopeOption.Required, 
            TimeSpan.Zero)) 
{  
    _repository.Save(entity);   
} // no Complete(), but the transaction still commits 

是期待它,以爭取其在交易中TransactionScope塊內部剛剛打開的SQLite連接?

同樣,我不能提供一個新的連接,因爲這將清除數據庫。

使用NHibernate 3.0和SQLite 1.0.66.0,這兩個最新版本在寫作時。

注: NHibernate的ITransaction對象上使用transaction.Rollback()正確回滾事務,它只是TransactionScope支持,似乎並沒有工作。

+0

不SQLite的(及其驅動程序)的支持分佈式事務,或者是它明確瞭解TransactionScope? – 2011-03-20 17:02:03

+0

@diego:是的,根據SQLite ADO.NET提供商論壇上的帖子,TransactionScope已經支持了幾年。 「自動分佈式事務登記」也是其主頁上記錄的功能之一。 – andreialecu 2011-03-20 17:10:23

+0

並且如果您在作用域結束後檢查,數據是否仍然存在? – 2011-03-20 17:37:13

回答

1

我想我可能已經找到了原因。如果連接未從TransactionScope塊內部打開,則不會在事務中註冊。

有一些信息: http://msdn.microsoft.com/en-us/library/aa720033(v=vs.71).aspx

解決方案:

我已經在我的倉庫一個.BeginTransaction()方法,所以我想我會爭取手動在環境事務有連接。

這是我結束了代碼:

/// <summary> 
    /// Begins an explicit transaction. 
    /// </summary> 
    /// <returns></returns> 
    public ITransaction BeginTransaction() 
    { 
     if (System.Transactions.Transaction.Current != null) 
     { 
      ((DbConnection) Session.Connection).EnlistTransaction(System.Transactions.Transaction.Current); 
     } 
     return Session.BeginTransaction(); 
    } 

這裏就是我如何使用它:

using (var ts = new TransactionScope(TransactionScopeOption.Required, TimeSpan.Zero)) 
    using (var transaction = repository.BeginTransaction()) 
    { 
     repository.Save(entity); 
     transaction.Commit(); // nhibernate transaction is commited 
     // ts.Complete(); // TransactionScope is not commited 
    } // transaction is correctly rolled back now 
相關問題