简体   繁体   English

使用带有ORM(EF6)的自定义UOW的并行事务问题

[英]Parallel transaction issue using custom UOW with ORM(EF6)

A little background I'm trying to implement Generic Repository and UOW pattern along with Entity Framework as ORM.I have written custom UnitOFWork class with methods 我尝试将通用存储库和UOW模式与Entity Framework一起实现为ORM的一些背景知识。我已经使用方法编写了自定义UnitOFWork类

1.BeginTransaction. 1.BeginTransaction。 2.CommmitTransaction 3.RollBackTransaction 4.SaveChanges 5.IsInTransaction 6.Dispose. 2.CommitTransaction 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();
  }
   ....
   ....
}

My Generic repository class 我的通用存储库类

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);
  }
}

My 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);  

When I run this code to save person object it throws exception on context.SaveChanges() in CommitTransaction() method of UOW. 当我运行此代码以保存人员对象时,它将在UOW的CommitTransaction()方法中的context.SaveChanges()上引发异常。 Exception is "SqlConnection does not support parallel transactions." 例外是“ SqlConnection不支持并行事务。”

  1. Am I doing something wrong in the code? 我在代码中做错了吗?
  2. Transactions in UOW has some issues? UOW中的事务有一些问题?
  3. UOW transactions in conjunction with ORM are not supported? 不支持将UOW事务与ORM结合使用?
  4. If transactions are not supported then what is the purpose of UnityOfWork pattern when DbContext or any other ORM implements unitofwork pattern by default? 如果不支持事务,那么当DbContext或任何其他ORM默认实现unitofwork模式时,UnityOfWork模式的目的是什么?

I would appreciate your suggestions and comments. 非常感谢您的建议和意见。

[Update] I have fixed this issue by making context to accept current transaction which is already existing. [更新]我已通过使上下文接受已经存在的当前交易来解决此问题。 My fix was in the code CommitTransaction().I need your comments. 我的解决方法是在代码CommitTransaction()中。我需要您的注释。

From this. 由此。

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

To This. 对此。

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

Are there any downside for this approach? 这种方法有什么缺点吗? Please share your comments. 请分享您的评论。

  1. DbContext is NOT threadsafe - do not use dbcontext across threads. DbContext不是线程安全的-不要在线程之间使用dbcontext。
  2. Connection strings should make sure connections allow MARS. 连接字符串应确保连接允许MARS。 See Below. 见下文。
  3. UoW patterns are best practice with ORMs. UoW模式是ORM的最佳实践。 Supported by EF. 由EF支持。
  4. EF framework manage the transaction for you. EF框架为您管理交易。 No need to add Transaction handling to your basic repository class. 无需在基​​本的存储库类中添加事务处理。
    add object 1, change object2, remove object 3, 添加对象1,更改对象2,删除对象3,
    Then SaveChanges. 然后SaveChanges。
    Will be performed as a transaction by EF. 将由EF作为交易执行。 Without dirty uncommitted reads. 没有脏的未提交的读取。 If one of the updates fails, the changes are rolled back. 如果更新之一失败,则更改将回滚。
  5. Transactions via message queues. 通过消息队列进行交易。 EF and transaction scope for use with message queues General info on when you might want to use transactions in EF Considerations for using transactions and how to in EF 用于消息队列的EF和事务范围有关何时可能要在EF 中使用事务的一般信息有关使用事务的注意事项以及在EF中的操作方法

  6. Dispose of your Context instance ASAP. 尽快处置上下文实例。 Renew regularly is general recommendation 一般建议定期更新

connection String: see MultipleActiveResultSets=true 连接字符串:请参见MultipleActiveResultSets = true

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM