4

有人可以说我可以将 npgsql 与 TransactionScope 一起使用吗?

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

我和这个问题有同样的问题:TransactionScope and Npgsql - Prepared Transaction Issue

有没有将 npgsql 与 TransactionScope 一起使用的解决方案?

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

然后麻烦了:我使用文档中的代码,此代码执行以下操作:

  1. 创建事务范围
  2. 打开第一个连接
  3. 打开第二个连接
  4. 插入第一个连接
  5. 插入第二个连接
  6. 关闭第二个连接
  7. 关闭第一个连接
  8. 调用 scope.Complete()
  9. 处置范围

我等一下,经过 9 步数据将完全提交给 db。事实上,在第 6 步和第 7 步,npgsql 创建了准备好的事务,而在第 9 步什么也不做。最后我有两个准备好的事务,即块数据库。并且没有人可以提交或回滚它们。

一般来说,如果我在范围内调用完成之前关闭连接(例如由于异常),npgsql 会创建阻止表的准备好的事务。我认为这不是正确的行为。我等待范围处置数据将被完全提交或完全回滚。没有任何准备好的交易。

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

4

1 回答 1

8

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

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

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

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

我的印象是,问题的意图是使用前两个功能,而不是第三个。如果这是真的,则说明使用了错误的方法来管理事务。

在参考文档页面中有以合理方式使用事务和准备好的语句的示例。称为 System.Transactions 的功能TransactionScope似乎不需要您想要做的事情,并且似乎是让您陷入困境的原因。查看刚刚使用的示例conn.BeginTransaction()

于 2012-05-12T17:56:02.127 回答