具有多个 DbContext 的事务,每个事务在 Entity Framework 上都有自己的连接
Transaction with multiple DbContext and each one with its own connection on Entity Framework
我知道它看起来像是重复的,因为关于多个上下文中的事务有很多问题,但是 none 其中提到了这种情况。
设置
- SQL 开发机器上的 Server 2016(最新预览版)或 SQL 生产机器上的 Azure v12
- Entity Framework6.1.3
- .Net 4.5 在常规应用程序上
- 应用程序可以 运行 在 Azure 云服务或 VM 上,这并不重要
我们在代码中有什么
- 单个 TransactionScope
- 在 TransactionScope 外部 创建了两个 DbContext(它是由我们的依赖注入机制创建的,与 ASP.Net MVC 相关联,所以为了简单起见,我将其排除在范围之外样本)
- 每个上下文创建并维护自己的连接,该连接指向不同服务器上的不同数据库(如果 运行 在开发机器上连接,它也可以指向同一服务器,但仍然是不同的数据库)。
- 我们使用常规 SQL 身份验证 - 用户 ID 和密码(以防万一有人指出一些 post 谈论集成安全和 MSDTC 的问题,我们不在本地使用它,因为Azure SQL 不支持)
我们的代码示例
当我们做类似的事情时:
var contextA = new ContextA();
var contextB = new ContextB();
using(var scope = new TransactionScope())
{
var objA = new EntityA();
objA.Name = "object a";
contextA.EntitiesA.Add(objA);
contextA.SaveChanges();
var objB = new EntityB();
objB.Name = "object B";
contextB.EntitiesB.Add(objB);
contextB.SaveChanges();
scope.Complete();
}
我们收到什么
在调用 contextA.SaveChanges()
时抛出 System.Data.Entity.Core.EntityException
,并显示以下消息:
Root 异常: 基础提供程序在 EnlistTransaction 上失败。
内部异常:连接当前已登记事务。完成当前事务并重试。
所以,有人知道这个样本到底出了什么问题吗?
我们试图让一个事务使用多个上下文,每个上下文都有自己的数据库连接。显然,由于每个上下文的数据都在不同的数据库服务器上(在生产中),我们不能使用接收 DbConnection 并将其与两个上下文共享的 DbContext ctor,因此共享 DbConnection 不是一个选项。
非常感谢,非常感谢任何帮助。
据我所知,SQL Azure 不支持分布式事务。 Source
Azure SQL 数据库现在支持使用 TransactionScope 的分布式事务。参见 TransactionScope() in Sql Azure。
我知道它看起来像是重复的,因为关于多个上下文中的事务有很多问题,但是 none 其中提到了这种情况。
设置
- SQL 开发机器上的 Server 2016(最新预览版)或 SQL 生产机器上的 Azure v12
- Entity Framework6.1.3
- .Net 4.5 在常规应用程序上
- 应用程序可以 运行 在 Azure 云服务或 VM 上,这并不重要
我们在代码中有什么
- 单个 TransactionScope
- 在 TransactionScope 外部 创建了两个 DbContext(它是由我们的依赖注入机制创建的,与 ASP.Net MVC 相关联,所以为了简单起见,我将其排除在范围之外样本)
- 每个上下文创建并维护自己的连接,该连接指向不同服务器上的不同数据库(如果 运行 在开发机器上连接,它也可以指向同一服务器,但仍然是不同的数据库)。
- 我们使用常规 SQL 身份验证 - 用户 ID 和密码(以防万一有人指出一些 post 谈论集成安全和 MSDTC 的问题,我们不在本地使用它,因为Azure SQL 不支持)
我们的代码示例
当我们做类似的事情时:
var contextA = new ContextA();
var contextB = new ContextB();
using(var scope = new TransactionScope())
{
var objA = new EntityA();
objA.Name = "object a";
contextA.EntitiesA.Add(objA);
contextA.SaveChanges();
var objB = new EntityB();
objB.Name = "object B";
contextB.EntitiesB.Add(objB);
contextB.SaveChanges();
scope.Complete();
}
我们收到什么
在调用 contextA.SaveChanges()
时抛出 System.Data.Entity.Core.EntityException
,并显示以下消息:
Root 异常: 基础提供程序在 EnlistTransaction 上失败。
内部异常:连接当前已登记事务。完成当前事务并重试。
所以,有人知道这个样本到底出了什么问题吗?
我们试图让一个事务使用多个上下文,每个上下文都有自己的数据库连接。显然,由于每个上下文的数据都在不同的数据库服务器上(在生产中),我们不能使用接收 DbConnection 并将其与两个上下文共享的 DbContext ctor,因此共享 DbConnection 不是一个选项。
非常感谢,非常感谢任何帮助。
据我所知,SQL Azure 不支持分布式事务。 Source
Azure SQL 数据库现在支持使用 TransactionScope 的分布式事务。参见 TransactionScope() in Sql Azure。