将两个独立数据源的事务处理为一个

时间:2009-10-29 16:46:20

标签: database web-services transactions

我有两个数据源:遗留数据库(Web服务)和数据库数据源。现在,当我处理请求时,我对两者都进行了更改。如果出现错误,我想回滚它们。

try
{
  legacy.Begin(); db.Begin();
  legacy.MakeChanges(); db.MakeChanges();
}
except (Exception)
{
  legacy.Rollback(); db.Rollback();
}

问题是,如果旧版在回滚期间抛出(即网络错误)怎么办? db.Rollback()将不会被执行。反之亦然。 我看到的解决方案是:

legacy.Begin(); 
try
{
  db.Begin();
  try
  {
      legacy.MakeChanges(); db.MakeChanges();
  }
  except (Exception)
  {
    db.Rollback();
    throw;
  }
}
except (Exception)
{
  legacy.Rollback(); 
  throw;
}

可以接受吗?有更好的解决方案吗?

1 个答案:

答案 0 :(得分:1)

您正在有效地推出自己的两阶段提交事务。一个完全强大的解决方案需要两个资源的合作,通常最好使用支持2PC的事务管理器。

这里的根本问题是你没有保护自己的应用程序失败(他扮演事务管理器的角色),因此无法保证你可以回滚那些遗产。 考虑一下你的app即将调用legcacy.Rollbock()的失败。你现在没有记录你正处于“交易”的中间,所以当你的应用程序回来时,你没有理由去执行该回滚。

可能的方法:

1)。使用true 2PC,这只有在您的WebSerice具有事务功能(技术上可行但实际上不太可能)时才有可能。

2)。容忍一些不一致的风险。许多系统实际上无意中这样做了,

3)。尝试恢复你想要的恢复但接受它可能会失败。添加某种形式的审计跟踪,允许检测不确定的结果,从而允许稍后手动补丁。因此,您可以添加一些审计日志记录,以便您检测mismtached活动。这可以看作是一种非常手动的2PC方法。