我们正在使用Entity Framework 6并正在处理以下要求:
我们正在将数据写入两个不同的独立数据库,我们称之为Main和External,它们都存在于同一个SQL Server实例上,用于连接它们的连接字符串是相同的,除了初始目录值
在应用程序中,每个DB都有自己的EF DBContext。
主数据库有一个AuditLog表,其中记录了数据更改。
外部数据库上发生的数据更改需要记录在主数据库中的AuditLog表中。
由于某些限制并不重要,讨论我们实现的方式是让ExternalContext有一个MainContext的引用,以便每当调用ExternalContext.SubmitChanges时调用MainContext.SaveAuditLogs,就像这样(只显示相关代码) :
public class ExternalContext : IDataContext
{
private readonly IAuditLogContext auditLogContext;
public ExternalContext (IAuditLogContext auditLogContext){
this.auditLogContext = auditLogContext;
}
public override void SaveChanges()
{
base.SaveChanges();
this.auditLogContext.SaveAuditLogs(auditLogs);
}
}
public class MainContext : IAuditLogContext
{
public void SaveAuditLogs(List<AuditLog> auditLogs)
{
this.Set<AuditLog>().AddRange(auditLogs);
this.SaveChanges();
}
}
如何使用它的一个例子:
public class SomeBusinessClass
{
private readonly IDataContext dataContext;
public SomeBusinessClass(IDataContext dataContext)
{
this.dataContext = dataContext;
}
public void SomeOperation(Entity someEntity)
{
.....
using(var scope = new TransactionScope())
{
this.dataContext.Insert(someEntity);
this.dataContext.SaveChanges();
}
scope.Complete();
}
}
为此,分布式事务处理协调器服务需要运行。在开发环境中进行测试时,它可以正常工作,但在QA环境中,它会因错误消息而失败,就像分布式事务处理协调器即使没有运行一样。
显然这是因为在我们的开发环境中,数据库服务器和Web服务器在QA中是相同的计算机天气,它们是两个独立的盒子,当有多个服务器并且这两个操作在TransactionScope中运行时,DTC不喜欢它,如果我们删除TransactionScope,那么它在两种环境下都能正常工作,但是如果AuditLog失败则不会回滚整个事务。
我们怎样才能做到这一点?
谢谢。