【问题标题】:.Net Core Connection currently has transaction enlisted.Net Core Connection 当前已登记事务
【发布时间】:2018-06-21 03:13:34
【问题描述】:

我正在使用 .Net Core 2.1 编写集成测试我有一个看起来像这样的测试:

private TransactionScope scope;

[TestCleanup]
public void TestCleanup()
{
    this.scope.Dispose();
}

[TestInitialize]
public void VerifyUsersHaveBeenSeeded()
{
    var transactionOptions = new TransactionOptions { 
             IsolationLevel = IsolationLevel.ReadCommitted 
    };
    //I've also tried using TransactionScopeOption.Required
    this.scope = new TransactionScope(TransactionScopeOption.RequiresNew,
                     transactionOptions);
}

//Note I am using an MDF file during Testing.
protected AstootContext GetContext()
{
    var optionsBuilder = new DbContextOptionsBuilder<AstootContext>();
    optionsBuilder.UseSqlServer(this.ASTOOT_CONNECTION_STRING);
    var context = new AstootContext(optionsBuilder.Options);
    return context;
}


[TestMethod]
public async Task RestEzServiceVerifyUpdate()
{
    var context = this.GetContext();
    var expectedResult = context.Users.First();

    var restEzService = GetDefaultService<User, UserDTO>(context);
    var key = new object[] { expectedResult.Id };

    var dto = await restEzService.Get(key);

    var updatedName = "Updated";
    dto.FirstName = updatedName;

    var updatedDTO =  await restEzService.Update(key, dto);
    Assert.IsTrue(updatedDTO.FirstName == updatedName);
    updatedDTO.Should().BeEquivalentTo(expectedResult, 
        o => o.Excluding(x => x.UniqueIdentifier).Excluding(x => x.FirstName));

    context.Dispose();
}

更新方法调用:

var entity = await this._context.FindAsync(id).ConfigureAwait(false);
this.applyDTOToEntity(entity, dto);
await this._context.SaveChangesAsync().ConfigureAwait(false);

当它调用保存更改时,我得到一个错误:

System.InvalidOperationException:连接当前已登记事务。完成当前事务并重试。

我从上下文中调用的唯一位置是 1. 要在测试中获得预期结果,2. 获取更新的实体,3. 保存更改。

我将 transactionScopeOptions 设置为 Requires New,为什么会出现此错误?

【问题讨论】:

  • 您是否在 Update 方法中创建了新的 DbContext?
  • 不,它被传递到服务中
  • 添加GetContext方法

标签: c# entity-framework transactions .net-core mstest


【解决方案1】:

TransactionScopeOption.RequiresNew 尝试创建新事务。您确定吗,new TransactionScope 处没有交易。

也许,你需要用TransactionScopeOption.Required替换它

你也使用 async/await,所以添加到范围选项TransactionScopeAsyncFlowOption.Enabled

using (var scope = new TransactionScope(... ,
  TransactionScopeAsyncFlowOption.Enabled))

【讨论】:

  • 我只是将范围选项更改为使用Required,它具有相同的行为
  • @johnny5 在创建新范围之前检查Transaction.Current 是否为空
  • 当我去保存 Transaction.Current 为空时,我还进一步隔离了问题,所以它只调用更新,所以它只调用数据库来获取实体,并调用SaveChanges
  • @johnny5 尝试TransactionScopeAsyncFlowOption 选项,更新答案
  • 谢谢这就是原因
猜你喜欢
  • 2017-03-27
  • 2018-11-11
  • 1970-01-01
  • 1970-01-01
  • 2020-03-26
  • 1970-01-01
  • 2022-01-08
  • 2017-09-18
  • 2023-02-13
相关资源
最近更新 更多