DbContextTransaction和多线程:连接已经在一个事务中,不能参与另一个事务

本文关键字:事务 一个 不能 另一个 多线程 连接 DbContextTransaction | 更新日期: 2023-09-27 17:51:01

当我试图用多个线程调用相同的方法时,我得到了这个错误:连接已经在一个事务中,不能参与另一个事务。EntityClient不支持并行事务

我发现我的问题在某种程度上类似于此:来自实体框架的SqlException -不允许新事务,因为有其他线程在会话中运行

<<p> 我的场景/strong>:我有一个由多个头实例化的类,每个线程-新实例:
public MarketLogic()
{ 
      var dbContext = new FinancialContext();
      AccountBalanceRepository = new AccountBalanceRepository(dbContext);
      CompositeTradeRepository = new CompositeTradeRepository(
         new OrderRepository(dbContext)
         , new PositionRepository(dbContext)
         , new TradeRepository(dbContext));
      CompositeRepository = new CompositeRepository(
         new LookupValueRepository(dbContext)
         , new SecurityRepository(dbContext)
         , new TransactionRepository(dbContext)
         , new FinancialMarketRepository(dbContext)
         , new FinancialMarketSessionRepository(dbContext)
         );
}

MarketLogic类中,SavePosition()用于使用实体框架DbContext将信息保存到数据库中。( SaveChanges () )方法。

private void SavePosition()
{
   using (DbContextTransaction transaction = CompositeTradeRepository.OrderRepository.DbContext.Database.BeginTransaction())
   {
            try
            {
                   // business logic code, **this take some times to complete**.
                   position = EntityExistsSpecification.Not().IsSatisfiedBy(position)
                              ? CompositeTradeRepository.PositionRepository.Add(position)
                              : CompositeTradeRepository.PositionRepository.Update(position);
                   transaction.Commit();
            }
            catch (Exception exception)
            {
                // some code
                transaction.Rollback();
            }
    }
}
public Position Add(Position position)
{
   // some code
   // context is a instance of FinancialContext, this class is generated by Entity Framework 6
   context.SaveChanges();
}

在我的场景中,当有2个线程和更多的线程尝试调用new MarketLogic(). saveposition ().

时,问题发生了。

我可以看到,当第一个事务尚未完成时,第二个线程进来并开始一个新事务。

但我不明白为什么2个线程在不同的DbContext对象,但错误仍然发生

这是怎么回事?还是我错过了什么?

DbContextTransaction和多线程:连接已经在一个事务中,不能参与另一个事务

我的错,我把存储库保持为静态,所以所有线程共享相同的存储库,这意味着它们共享相同的DbContext,这导致了当EF还没有完成允许更改和对SaveChanges()的其他调用时出现问题。所以EF抛出了异常