我需要在单个事务中保存到两个不同的SQL Azure联合数据库,这样如果出现故障,我可以回滚所有更改。现在,我有两个独立的代码块,它们彼此独立地进行交易。我尝试使用TransactionScope,但显然SQL Azure不支持它。
using (EVENTContext dc = new EVENTContext(
GetConnectionString(1)))
{
string federationCmdText = @"USE FEDERATION [fed] ([dist] = '"+ GetDist(1) +"') WITH FILTERING = OFF, RESET";
((IObjectContextAdapter)dc).ObjectContext.Connection.Open();
dc.Database.ExecuteSqlCommand(federationCmdText);
dc.EVENTS.Add(e);
dc.SaveChanges();
}
using (EVENTContext dc = new EVENTContext(
GetConnectionString(2)))
{
string federationCmdText = @"USE FEDERATION [fed] ([dist] = '"+ GetDist(2) +"') WITH FILTERING = OFF, RESET";
((IObjectContextAdapter)dc).ObjectContext.Connection.Open();
dc.Database.ExecuteSqlCommand(federationCmdText);
dc.EVENTS.Add(e2);
dc.SaveChanges();
}
如何在单个交易中保存到多个数据库?我最近开始阅读工作单元,但我不确定这是否是我需要的。
答案 0 :(得分:0)
不幸的是你做不到;它不受支持。您可以做的最接近的事情是将记录存储在挂起状态(在为此目的添加的列中),如果两者都提交,则将记录状态更改为Active(或沿着这些行的某些内容)。换句话说,这是您需要自己管理并将这些操作视为长时间运行的事情。
答案 1 :(得分:0)
好的,在考虑了一段时间之后回答我自己的问题。这是我要做的事情:
1)为每个用户操作生成一个操作ID(无论它是什么)并将其写入根数据库中的表
2)将此操作ID附加到每一行,以便我可以跟踪为哪个操作添加了哪些行
3)单独提交每个数据库
4)从根数据库表中删除操作ID
所有这些步骤都是一个用户操作的一部分,如果在一个步骤中抛出异常,则不会执行以下步骤。
在应用程序端,然后检查是否在联合表中返回的操作ID出现在根数据库表中。如果是这样,则提交更改时出错。如果没有,这是一次成功的交易。
最后,我可以运行一个辅助角色,该角色定期从根数据库表中获取一个操作ID,并清除具有该操作ID的所有行,并在删除它们之后,还删除操作ID。
答案 2 :(得分:0)
连接到Azure SQL DB时,不支持TransactionScope。您可以独立提交单独的上下文(如代码示例中所示),或者您必须按上述方式实现自己的补偿逻辑。两者都不再需要,因为Azure DB现在支持TransactionScope。见TransactionScope() in Sql Azure。