我有一种情况,我必须提交一部分代码作为它自己的事务。
我已经创建了一个表subtransaction_tbl
:
CREATE TABLE subtransaction_tbl
(
entryval integer
)
以及plpython3u语言中的函数:
CREATE FUNCTION subtransaction_nested_test_t() RETURNS void
AS $$
plpy.execute("INSERT INTO subtransaction_tbl VALUES (1)")
with plpy.subtransaction():
plpy.execute("INSERT INTO subtransaction_tbl VALUES (2)")
$$ LANGUAGE plpython3u;
第一种情况:
BEGIN TRANSACTION;
INSERT INTO subtransaction_tbl VALUES (4);
select subtransaction_nested_test_t();
COMMIT TRANSACTION;
表中的条目正确:1、2、4
第二种情况:
BEGIN TRANSACTION;
INSERT INTO subtransaction_tbl VALUES (4);
select subtransaction_nested_test_t();
ROLLBACK TRANSACTION;
表中的值未填充
我希望1
或2
应该添加到表
中,但出乎意料的是没有插入任何值。我想象函数打开了一个新的子事务,它不应该依赖于父事务。如果我是对的,请告诉我。
Postgres中是否存在自主交易?或者我必须修改我的plpython3u函数吗?
在Postgres 11之前的Postgres中没有自治事务,在Postgres 11中添加了SQL过程。函数中所做的一切都随事务一起回滚。
以下是对该功能的讨论:
在Postgres 10或更早版本中,一种解决方法是(ab-)使用dblink:
还有相关的< code >保存点概念。(不是一回事!):
plpython有子事务(withplpy.subtransaction():
),但这与自主事务不同。没有单独的COMMIT
。它所做的就是将几个语句捆绑在一起,使它们成为原子。没有它,如果中间某个地方发生异常,并且您捕获了该异常,则只会执行该异常之前的代码。如果您将其包装到子事务中,则要么全部要么没有。这就像使用SAVEPOINT
,而不是自主事务。每个留档:
子事务上下文管理器不捕获错误,它只确保在其作用域内执行的所有数据库操作将被自动提交或回滚。
Postgres确实支持嵌套事务,但它们不同于传统的SQL,更像是具有嵌套部分点的事务。
在顶层,您总是有典型的BEGIN/COMMIT/ROLLBACK
,在嵌套级别,您必须使用以下命令:
SAVEPOINT name
-创建一个新的保存点,名称为事务唯一RELEASE SAVEPOINT name
-提交保存点,尽管只有在包含事务提交ROLLBACK TO SAVEPOINT name
-回滚保存点您还必须确保:
最后一点有点棘手,除非你使用一个可以自动完成这项工作的库。
当我写pg-promise时,我确保这两个条款得到保证:
另请参阅PostgreSQL嵌套事务的限制解释…
据我所知,当您尝试在提交前一个事务之前开始一个事务时,会发生这种异常。然而,我不明白为什么在我的情况下会有这种例外。 我有一个Web应用程序与以下servlet: 这是我的Compte对象: 这是我的DAO的接口: 这就是它的实施: 另外,这是我的Spring配置: 关联的应用程序。属性文件包含以下行: 最后,我有以下servlet过滤器,从这里开始事务: 这是在网络上映射的。如下所示的xml文件
问题内容: JTA为什么不支持嵌套事务?是因为实现它们的复杂性(我对此表示怀疑)还是某些设计原则? 问题答案: (正如@Piotr Nowicki指出的那样,JTA 确实 允许嵌套事务,但这不是强制性的可选操作。) 为什么?这是无法确定地回答的问题之一,除非您是做出决定时“在房间里”的人之一。 将嵌套事务作为规范的一部分包括在内可能是固有的复杂性。或当时明显的复杂性;即他们不知道他们知道如何做一个
问题内容: 我需要确保许多并发用户能够访问数据库。虽然在每次提交后我都关闭了会话,但是有时我的代码遇到以下错误,但是当我几次执行相同的操作时,它会超过错误并可以正常工作。 我的hibernate状态是4.2.1。 我的密码 HibernateUtil 组态 问题答案: 在您的“我的代码”代码段中,可能存在一些问题: 发生异常时,没有阻止关闭会话的块 您正在打电话,但这与有所不同。因此,不会清除。
我们继续上一章节的内容,大家应该记得我们 Lua 代码中是如何完成 ngx_postgres 模块调用的。我们把他简单改造一下,让他更接近真实代码。 local json = require "cjson" function db_exec(sql_str) local res = ngx.location.capture('/postgres',
环境: 我们有一个应用程序部署在 JBoss 4.2.3.GA 服务器中,它使用Hibernate 3.4 和 JTA 1.0。 有一个导入器创建或更新某些实体,然后导入一些数据。由于多种原因,大部分导入是在新事务中完成的,在每个事务中,在外部事务中创建/更新的实体可能会再次更新。 调用序列类似于以下伪代码: 服务1: 服务2: 问题: 现在的问题是,我们最终会遇到一个竞争条件,有几个事务试图锁定
问题内容: 运行removeUserFromConference方法时,遇到以下异常: 道方法: 模型类: 问题答案: 您可能已经开始了一笔交易,并尝试开始另一笔交易而没有提交或回滚上一笔交易。使用程序化事务划分时的惯用法如下: 这很麻烦且容易出错,这就是为什么使用EJB或Spring具有声明式事务如此有用的原因之一。