Npgsql,TransactionScope和准备好的事务

时间:2012-05-11 17:29:38

标签: postgresql transactions prepared-statement distributed-transactions npgsql

有人可以说我可以在TransactionScope中使用npgsql吗?

此处作为示例提供的代码:http://npgsql.projects.postgresql.org/docs/manual/UserManual.html不起作用。它只是在服务器上创建两个准备好的事务。

我遇到与此问题相同的问题:TransactionScope and Npgsql - Prepared Transaction Issue

在TransactionScope中使用npgsql有什么解决方案吗?

UPD: 首先我的目标: 我需要在我的软件中使用单个逻辑转换中的两个连接。对此最好的解决方案是TransactionScope。 Npgsql声明支持系统事务中的登记。

然后麻烦我: 我使用文档中的代码,这段代码做了下面的事情:

  1. 创建交易范围
  2. 打开第一个连接
  3. 打开第二个连接
  4. 插入第一个连接
  5. 插入第二个连接
  6. 关闭第二个连接
  7. 关闭第一个连接
  8. 调用scope.Complete()
  9. 处理范围
  10. 我等一下,9步后数据将完全提交给db。实际上,在步骤6和7中,npgsql创建准备好的事务,并且在步骤9中什么都不做。最后我有两个预先准备好的交易,即阻止数据库。并且没有人可以提交或回滚它们。

    通常如果我在范围内调用完成之前关闭连接(例如因为异常),npgsql会创建阻止表的准备事务。我认为这不是严谨的行为。我等待范围处理数据完全提交或完全回滚后。没有任何准备好的交易。

    您可以使用文档中的代码重复此错误。供参考Devart免费库工作正确。

1 个答案:

答案 0 :(得分:7)

在讨论答案之前,有三个独立的概念需要明确。

  1. 预备语句,它们与一个连接相关联,并提供一个“框架”语句,可以为每次执行插入新值,而无需解析和规划每次声明。好的一面是,您可以节省在每次执行时解析和规划语句所涉及的CPU时间。不利的一面是,计划是根据最佳“通用”计划完成的,这可能不是所有可分配值的最佳计划。准备好的陈述由NpgsqlCommand.prepare()方法创建。

  2. 事务,它们与连接相关联,并为一组相关的数据库活动提供上下文。一个事务的所有活动都在一个服务器的一个数据库中。交易由NpgsqlConnection.BeginTransaction()方法创建。

  3. 准备好的事务,它使用两阶段提交(2PC)来管理多个连接上的多个事务,可能在不同的连接,不同的数据库,不同的服务器上,或者使用完全不同的服务器产品作为一个逻辑“分布式交易”。此功能的使用应始终由高质量的事务管理器产品处理,该产品通常不属于参与分布式事务的任何数据库。目标是当所有相关事务都完成其工作时,事务管理器告诉每个事务“准备”提交。在响应事务管理器并指示成功或失败之前,每个人都会尝试做所有可能导致其失败的事情。如果所有事务在“准备”阶段成功,则事务管理器将告诉每个事务提交。准备好的事务必须能够在事务管理器请求它的某个稍后时间提交,即使服务器在“准备”阶段成功传递给事务管理器之后立即崩溃。看来支持使用TransactionScope构造函数创建自己的事务管理器。 我强烈建议不要尝试创建自己的ad hoc事务管理器。事务管理器是一个复杂而微妙的软件,很难做到正确,如果可能会产生严重的负面影响。 做得不错。

  4. 我的印象是问题的意图是使用前两个特征,而不是第三个特征。如果是这样,则使用错误的方法来管理事务。

    在引用的文档页面中,有一些以合理的方式使用事务和预准备语句的示例。名为System.Transactions的功能,使用TransactionScope类似乎不需要你想做什么,似乎是让你陷入困境的原因。查看仅使用conn.BeginTransaction()的示例。