PostgreSQL – 在函数中启动一个事务块
我正在尝试在函数内部创建一个事务块,所以我的目标是一次使用这个函数,所以如果有人使用这个函数而另一个想要使用它,他就不能直到第一个完成我创建这个功能:
CREATE OR REPLACE FUNCTION my_job(time_to_wait integer) RETURNS INTEGER AS $$ DECLARE max INT; BEGIN BEGIN; SELECT MAX(max_value) INTO max FROM sch_lock.table_concurente; INSERT INTO sch_lock.table_concurente(max_value,date_insertion) VALUES(max + 1,now()); -- Sleep a wail PERFORM pg_sleep(time_to_wait); RETURN max; COMMIT; END; $$ LANGUAGE plpgsql; 但它接缝不起作用,我有一个错误语法错误BEGIN; 没有BEGIN;和COMMIT我得到一个正确的结果,我使用此查询来检查: -- First user should to wait 10 second SELECT my_job(10) as max_value; -- First user should to wait 3 second SELECT my_job(3) as max_value; 结果是: +-----+----------------------------+------------+ | id | date | max_value | +-----+----------------------------+------------+ | 1 | 2017-02-13 13:03:58.12+00 | 1 | +-----|----------------------------+------------+ | 2 | 2017-02-13 13:10:00.291+00 | 2 | +-----+----------------------------+------------+ | 3 | 2017-02-13 13:10:00.291+00 | 2 | +-----+----------------------------+------------+ 但结果应该是: +-----+----------------------------+------------+ | id | date | max_value | +-----+----------------------------+------------+ | 1 | 2017-02-13 13:03:58.12+00 | 1 | +-----|----------------------------+------------+ | 2 | 2017-02-13 13:10:00.291+00 | 2 | +-----+----------------------------+------------+ | 3 | 2017-02-13 13:10:00.291+00 | 3 | +-----+----------------------------+------------+ 所以第三个id = 3应该有max_value = 3而不是2,这是因为第一个用户选择max = 1并等待10秒而第二个用户选择max = 1并在插入前等待3秒,但是正确的解决方案是:我不能使用这个功能直到第一个完成,因为我想做一些安全和保护. 我的问题是: >我如何在函数内部创建一个Transaction块? 谢谢. 解决方法
好的,所以你不能在函数中进行COMMIT.您可以有一个保存点并回滚到保存点.
您可能的最小事务是服务器从客户端解析并执行的单个语句,因此每个事务都是一个函数.但是,在交易中,您可以拥有保存点.在这种情况下,您将查看PostgreSQL的异常处理部分来处理这个问题. 然而,这不是你想要的.您希望(我认为?)数据在长时间运行的服务器端操作期间可见.为此,你有点不走运.在运行函数时,您无法真正增加事务ID. 根据我认为的良好做法(最好到最差),你有几个选择: >将逻辑分解为更小的切片,每个切片将数据库从一个一致状态移动到另一个状态,并在单独的事务中运行它们.>在数据库中使用消息队列(如pg_message_queue),外加一个外部工作程序,以及运行步骤并为下一步生成消息的内容.缺点是这增加了更多的维护.>使用像dblink或pl / python或pl / perlu这样的函数或框架连接回db并在那里运行事务. ICK …. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |