处理“异步”提交的好方法是什么?

时间:2009-11-20 19:52:05

标签: oracle transactions transactionscope odp.net msdtc

我有一个使用ODP.NET从Oracle数据库读取数据的WCF服务。该服务还会间接地写入数据库,因为所有更新和插入都是通过我通过COM +访问的旧层业务逻辑实现的,我将其包装在TransactionScope中。较旧的层通过ODBC连接到Oracle,而不是ODP.NET。

我遇到的问题是,由于Oracle使用两阶段提交,并且由于较旧的业务层使用的是ODBC而不是ODP.NET,因此事务有时会返回{{1在数据实际可用于从服务层读取之前。

我在Stack Overflow上也看到a similar post about a Java user having trouble like this

来自Oracle posted that there isn't much I can do about this问题的代表:

  

这可能是由于OLETx的方式   ITransaction :: Commit()方法的行为。   在2PC的第1阶段之后(即   准备阶段)如果一切都成功,   即使资源,提交也可以返回   经理们没有真正承诺。   毕竟成功的“准备”是   保证资源管理者   在此之后不能随意中止   点。因此即使是资源   经理无法承诺,因为它   没有收到“提交”通知   来自MSDTC(由于说   沟通失败),   组件的提交请求返回   成功。如果从中选择行   您可以立即使用这些表格   有时看到实际的提交发生   你已经在数据库中   执行你的选择。你的选择会   因此,不会看到新的行   一致的读语义。有   我们在Oracle中无能为力   作为“继承之后的成功”   成功的第1阶段“优化是   MSDTC实施的一部分。

所以,我的问题是:

我应该如何处理可能的延迟(通过标题的“asyc”)问题,找出2PC的第二部分何时实际发生,所以我可以肯定我插入的数据(间接)实际上是可用的在TransactionScope.Commit()调用返回后选择?

大型系统如何处理数据可能无法立即读取的事实?

1 个答案:

答案 0 :(得分:1)

我假设整个事务已经准备好并且由TransactionManager决定提交结果,因此最终(除了启发式损坏)资源管理器将收到它们的提交消息并完成。但是,无法保证可能需要多长时间 - 可能是几天,没有超时适用,在准备资源管理器中投票“提交”必须等待听取集体结果。

在这些条件下,最简单的方法是采取“理解,我们正在思考”的方法。您的请求已被理解,但您实际上并不知道结果,这就是您告诉用户的内容。是的,在所有理智的情况下,请求将完成,但在某些情况下,操作员实际上可以选择手动干预交易(并且可能会导致启发式损坏。)

更进一步,您可以启动一个新事务并执行一些查询以查看数据是否存在。现在,如果要填充结果屏幕,您自然会进行查询等操作。问题是如果预期的结果不存在该怎么办。再次,告诉用户“您最近的请求正在处理中,点击刷新以查看它是否完整”。或者自动重试(我不太喜欢自动重试 - 更喜欢教育用户它实际上是异步操作。)