我正在Postgres开发一个PL函数,在其中我正在修改表的记录,根据一些逻辑,然后我执行一个最终查询(基本上是计数),如果我得到的数字是正数,我扔回滚事务的一个例外(因为PostgreSQL的函数不明确支持事务)。
这是模拟交易的好方法吗?你有更好的建议吗?
PS:我正在使用PostgreSQL 9.2,但我很快就会迁移到9.3,如果这可能会有所帮助。
答案 0 :(得分:4)
如果你想在一个函数中中止事务,那么是的,提出异常是一个不错的选择。
您可以使用函数中的BEGIN ... EXCEPTION
块在PL / PgSQL函数中使用子事务。使用内部BEGIN ... EXCEPTION
块并在其中RAISE
使用用户定义的SQLSTATE进行异常。在EXCEPTION
块中捕获异常。
RAISE
块中的ERROR
(BEGIN ... EXCEPTION
或更高)将回滚该块内完成的工作,就好像您使用了SAVEPOINT
和{{ 1}}。
函数无法强制回滚顶级事务;如果ROLLBACK TO SAVEPOINT
异常,外部pl / pgsql函数可以在RAISE
块中捕获异常,或者客户端可以使用BEGIN ... EXCEPTION
。
答案 1 :(得分:3)
我过去曾使用过这个解决方案。问题在于PLPGSQL语言不支持使用SAVEPOINT和ROLLBACK。事务 wrap 函数,而不是相反。
RAISE是通知客户端函数内某些内部条件的正确方法。有几个级别的RAISE,“最差”是EXCEPTION,它将中止/回滚你的交易,除非有东西捕获异常并抑制它。
进行测试,请使用
`RAISE DEBUG 'some comment %', var;`
如果您想在日志中添加内容,但又不想回滚,则可以(通常)提出警告。 (任何级别的RAISE都可以转到您的日志,这取决于您的配置)