2013-11-21 83 views
0

一點背景我試圖與實體框架一起實現通用庫和UOW圖案ORM.I寫了定製的UnitOfWork類方法並行交易問題

1.BeginTransaction 。 2.CommmitTransaction 3.RollBackTransaction 4.SaveChanges 5.IsInTransaction 6.Dispose。

public class UnitOfWork: IUnitOfWork 
{ 
    private DbTransaction transaction; 
    private readonly DbContext context; 
    public UnitOfWork(DBContext dbContext) 
    { 
    context = dbContext ; 
    } 
    public void Begintransaction() 
    { 
    transaction = context.Database.Connection.BeginTransaction(isolationLevel); 
    } 
    public void CommitTransaction() 
    { 
    context.SaveChanges(); 
    transaction.Commit(); 
    ReleaseCurrentTransaction(); 
    } 
    .... 
    .... 
} 

我一般倉儲類

public class Repository : IRepository 
{ 
    private dbContext; 
    protected DBContext Context 
    { 
    get 
    { 
     return dbContext != null? dbContext : dbContext = GetContextFromFactory(); 
    } 
    } 
    public void Add<T>(T entity) 
    { 
    dbContext.Set<T>.Add(entity); 
    } 
} 

我PersonRepository。

public class PersonRepository : Repository 
{ 
    public void AddPerson(Person person) 
    { 
    using(var uow = new UnitOfWork(Context) 
    { 
     try 
     { 
     uow.BeginTransaction(); 
     Add(person); 
     uow.CommitTransaction(); 
     } 
     catch (Exception ex) 
     { 
     uow.RollBackTransaction(); 
    log.Error("This Exception:",ex); 
     } 
    } 
    } 
} 

var repo = new PersonRepository(); 
Person person = GetPerson(); 
repo.AddPerson(person); 

當我運行這段代碼保存它拋出CommitTransaction上context.SaveChanges)異常((UOW)的方法的人對象。 例外是「SqlConnection不支持並行事務」。

  1. 我在做一些錯誤的代碼?
  2. UOW中的交易有一些問題?
  3. 不支持與ORM一起使用的UOW事務?
  4. 如果不支持事務又是什麼UnityOfWork模式的目的時的DbContext或任何其他ORM實現默認的UnitOfWork模式?

我會感激你的建議和意見。

[更新] 我已通過使上下文接受當前已存在的事務來解決此問題。我的修復程序在代碼CommitTransaction()中,我需要您的意見。

從這。

public void CommitTransaction() 
    { 
    context.SaveChanges(); 
    transaction.Commit(); 
    ReleaseCurrentTransaction(); 
    } 

對此。

public void CommitTransaction() 
    { 
    context.UseTransaction(this.transaction); 
    context.SaveChanges(); 
    transaction.Commit(); 
    ReleaseCurrentTransaction(); 
    } 

這種方法有什麼不足嗎?請分享您的意見。

回答

1
  1. DbContext不是線程安全的 - 不要在線程間使用dbcontext。
  2. 連接字符串應確保連接允許MARS。見下文。
  3. UoW模式是ORM的最佳實踐。由EF支持。
  4. EF框架爲您管理交易。無需將事務處理添加到基本存儲庫類中。
    附加對象1,改變Object2的,刪除對象3,
    然後調用SaveChanges。
    將由EF執行交易。沒有骯髒的未提交的讀取。 如果其中一個更新失敗,則更改將回滾。
  5. 經由消息隊列交易。 EF and transaction scope for use with message queues 上時,你可能想在EF使用交易 Considerations for using transactions and how to in EF

  6. 您的上下文實例的儘快處置一般信息。定期更新是一般建議

連接字符串:看MultipleActiveResultSets =真

<connectionStrings> 
    <add name="myConn" connectionString="Data Source=localhost;Initial Catalog=MyDbName ;Integrated Security=True;MultipleActiveResultSets=True;App=EntityFramework" providerName="System.Data.SqlClient" /> 
</connectionStrings> 
+0

我的DbContext範圍是每對HttpRequest的Web應用程序和Windows它是共享的是去上班靜態context.Is?請看我的更新,讓我知道你的想法。 – Mady

+0

我希望httpreq能夠正常工作。但不明白爲什麼你想手動控制範圍。它看起來像單個數據庫存儲庫UoW更新。爲什麼不讓EF做到這一點。在Windows應用程序中長時間運行靜態上下文時要小心。你不能使用多線程,並且隨着時間的推移可能導致臃腫的上下文。即使在Windows應用程序中,建議更新上下文。它很便宜。 –

+0

我沒有明白你的觀點**但不明白你爲什麼要手動控制範圍。**我認爲這應該是這樣,我不知道在構建選項。可能是因爲我試圖遵循持久性無知模式。請賜教。順便說一下,我有一個web服務和windows服務使用庫。現在我有單一的存儲庫。謝謝你的時間。 – Mady