2013-03-20 66 views
4

在通過ServiceStack的OrmLite在SQLite中創建並提交事務後,我無法繼續併發出任何查詢。ORMLite下的SQLite不允許在事務完成後執行任何操作

例如,下面的測試失敗:

 [Test, Explicit] 
     public void Can_query_after_transaction_is_committed() 
     { 
      var connection = new OrmLiteConnectionFactory(":memory:", false, SqliteDialect.Provider, true); 
      using (var db = connection.OpenDbConnection()) 
      { 
       db.DropAndCreateTable<SimpleObject>(); 
       var trans = db.OpenTransaction(); 
       db.Insert(new SimpleObject{test="test"}); 
       trans.Commit(); 
       Assert.DoesNotThrow(()=> db.Select<SimpleObject>()); //throws 
      } 
     } 

class SimpleObject{public string test { get; set; }} 

我得到的例外是:「交易不與命令的連接相關聯的」失敗周圍OrmLite的that line。但是,我根本不應該參與交易。

當我使用SQL Server與代碼提供商像

new OrmLiteConnectionFactory(
        @"Data Source=.\SQLEXPRESS;Initial Catalog=TestEmpty;Persist Security Info=True;User ID=db;Password=db;", 
        false, SqlServerDialect.Provider, true);*/ 

本次測試工作正常。

我結束了交易不正確嗎?這是ServiceStack.OrmLite中的錯誤嗎?

回答

7

原來我在使用的版本中已發現類似問題reportedfixed。經過比較我的測試與the passing one我發現我dindn't處置()我的交易。

最後答案是:該交易必須處置。如果不是,則使用SQLite時代碼將失敗。

下測試通過:

 public void Can_query_after_transaction_is_committed() 
     { 
      var connection = new OrmLiteConnectionFactory(":memory:", true, SqliteDialect.Provider, true); 
      using (var db = connection.OpenDbConnection()) 
      { 
       db.DropAndCreateTable<SimpleObject>(); 
       using (var trans = db.OpenTransaction()) 
       { 
        db.Insert(new SimpleObject {test = "test"}); 
        trans.Commit(); 
       } 
       Assert.DoesNotThrow(()=> db.Select<SimpleObject>()); 
      } 
     } 
2

我的問題是相似的,我搜查這裏。試圖編寫一個單元測試來測試我的服務,我得到了同樣的「事務不與命令的連接關聯」異常。我的情況不同之處在於,我正在使用的唯一事務(在我測試的服務中)正確地處理了它的連接,所以我不認爲這適用。

(我使用的ServiceStack v3.9.71)

我的測試代碼(失敗)是這樣的:

[Test] 
public void Test_Service_Delete() { 
    var DatabaseFactory = new OrmLiteConnectionFactory(":memory:", false, SqliteDialect.Provider, true); 

    using (var db = DatabaseFactory.OpenDbConnection()) { 
     var parentId = db.InsertParam(new ParentObject { name = "Bob" }, true); 
     db.Insert(new ChildObject { ParentId = parentId, name = "Sam" }); 

     var service = Container.Resolve<TestService>(); 
     var response = service.Delete(new DeleteRequestObject(parentId)); 

     Assert.That(db.Select<ParentObject>(parentId), Has.Count.EqualTo(0)); 
     Assert.That(db.Select<ChildObject>("ParentId = {0}", parentId), Has.Count.EqualTo(0)); 
    } 
} 

我TestService.Delete方法曾在它的事務(因爲它會刪除對象和任何相關的子對象),但它被包裹在一個使用塊,像這樣:

using (var db = DatabaseFactory.OpenDbConnection()) { 
    using (var transaction = db.BeginTransaction(IsolationLevel.ReadCommitted)) { 
     // do stuff here 
    } 
} 

不過,除了W「交易不與命令的連接相關聯」在調用service.Delete之後在第一行中拋出。

我首先要解決它(沒有工作)的嘗試是這樣的:

[Test] 
public void Test_Service_Delete() { 
    var DatabaseFactory = new OrmLiteConnectionFactory(":memory:", false, SqliteDialect.Provider, true); 

    int parentId; 
    using (var db = DatabaseFactory.OpenDbConnection()) { 
     parentId = db.InsertParam(new ParentObject { name = "Bob" }, true); 
     db.Insert(new ChildObject { ParentId = parentId, name = "Sam" }); 
    } 

    var service = Container.Resolve<TestService>(); 
    var response = service.Delete(new DeleteRequestObject(parentId)); 

    using (var db = DatabaseFactory.OpenDbConnection()) {  
     Assert.That(db.Select<ParentObject>(parentId), Has.Count.EqualTo(0)); 
     Assert.That(db.Select<ChildObject>("ParentId = {0}", parentId), Has.Count.EqualTo(0)); 
    } 
} 

什麼工作最終被包裹在一個事務服務呼叫後調用數據庫。

[Test] 
public void Test_Service_Delete() { 
    var DatabaseFactory = new OrmLiteConnectionFactory(":memory:", false, SqliteDialect.Provider, true); 

    int parentId; 
    using (var db = DatabaseFactory.OpenDbConnection()) { 
     parentId = db.InsertParam(new ParentObject { name = "Bob" }, true); 
     db.Insert(new ChildObject { ParentId = parentId, name = "Sam" }); 
    } 

    var service = Container.Resolve<TestService>(); 
    var response = service.Delete(new DeleteRequestObject(parentId)); 

    using (var db = DatabaseFactory.OpenDbConnection()) { 
     using (var transaction = db.OpenTransaction()) { 
      Assert.That(db.Select<ParentObject>(parentId), Has.Count.EqualTo(0)); 
      Assert.That(db.Select<ChildObject>("ParentId = {0}", parentId), Has.Count.EqualTo(0)); 
     } 
    } 
} 

我仍然模糊爲什麼這種解決方法工作,但我想我會記錄它的任何人跑到這。

相關問題