0

在创建复杂的过程时,整个函数被视为一个事务,或者如果我只是将整个函数放在一个begin ... end. 所以如果任何中间查询失败,系统就不会出现问题。那么我需要任何错误报告吗?或IF ... ELSE检查错误报告?(假设外键/唯一/等..约束已正确完成)

duplicate key value violates unique constraint如果或者我应该依赖数据库引擎,我是否需要自己提出错误?

在开发业务逻辑的同时编写存储过程时是否有任何模式可以遵循?

我正在使用PostgreSql并且PL/PgSQL我以前曾经这样ORM做过

4

1 回答 1

2

据我了解,您正在编写要从客户端代码执行的函数。一个函数的全部执行总是在一个事务中,不管你是否明确地BEGIN是一个事务,尽管你可以在 plpgsql 中通过使用子句编码BEGIN/END块来使用子事务。EXCEPTION此类子事务不是免费的,因此您只想在真正需要时使用它们。

如果可以以声明方式声明执行业务规则所需的不变量,那几乎总是比在触发器中使用命令式代码执行它们要好。 CHECK约束、PRIMARY KEY约束、FOREIGN KEY约束、UNIQUE约束和(PostgreSQL 独有的功能)EXCLUSION约束在覆盖用例时都应该使用而不是触发代码。

如果您使用的是 PostgreSQL 9.1 或更高版本,那么在开始之前做出的最大决定是您将使用什么策略来处理并发事务之间的竞争条件。两个主要选择是是否尝试跟踪所有可能的冲突并处理应用程序代码中的问题,或者仅使用可序列化事务(您可以在 postgresql.conf 文件中设置默认值)并让 PostgreSQL 解决问题。我在前者看到的最好的文章在这里:http ://www.postgresql.org/files/developer/concurrency.pdf而关于后者的链接是:

http://www.postgresql.org/docs/current/interactive/mvcc.html

http://wiki.postgresql.org/wiki/SSI

如果您使用SERIALIZABLE甚至REPEATABLE READ事务,您应该以某种方式运行查询,以提供对序列化失败的通用处理;也就是说,如果事务抛出异常并将 SQLSTATE 设置为“40001”或“40P01”,您应该回滚失败的事务并从头开始重试。您不想在运行查询的每个地方都将其逻辑嵌入到应用程序代码中。如今,许多开发框架都允许事务注释,这使得这很容易实现。我们只在我们的商店使用可序列化的交易,它确实简化了事情,如果你能证明交易本身做了正确的事情,

请注意,由于使用可序列化快照隔离,PostgreSQL 使用可序列化事务的性能非常接近于许多工作负载不太严格的隔离级别;如果你因为担心阻塞和死锁而一直回避这个想法——不要。PostgreSQL 9.1 中的可序列化事务没有像使用严格两阶段锁定 (S2PL) 的数据库那样的问题。

全面披露:在与麻省理工学院的 Dan RK Ports 的共同努力下,并根据 Sidney 大学的 Michael J. Cahill 等人的论文,我帮助实现了 PostgreSQL 版本 9.1 的可序列化快照隔离,因为我们需要在我的工作场所使用该功能。我没有从其他人使用它获得任何经济利益,但我个人认为这通常是要走的路。我希望,这更多是我从事该功能的原因,而不是从事该功能的结果

于 2012-04-09T12:33:59.703 回答