)
涉及的存储过程是从oracle那边直接拷贝过来后再修改过的,原先是动态SQL,这里简化为静态SQL。注意其中有个commit;根据PostgreSQL的要求,对事务增加begin...exception...end,否则会有错误或警告。示例脚本代码为:
create or replace function p1(pid int, pname varchar)
returns void as $$
begin
begin --pg对事务的要求
insert into t1 values(pid, pname);
commit;
exception
when others then
end; --pg对事务的要求
end;
$$ language plpgsql;
依次执行脚本创建存储过程、调用存储过程、查找示例表,结果如下:
postgres=# \i test1.sql
CREATE FUNCTION
postgres=# select p1(1, 'abc');
(1 行记录)
postgres=# select * from t1;
id | name
----+------
(0 行记录)
要插入的记录并不存在!惊喜不惊喜?意外不意外?
三、原因分析及解决
仔细查找有关资料,发现有这么一个解释:
Functions and trigger procedures are always executed within a transaction established by an outer
query — they cannot start or commit that transaction, since there would be no context for them to
execute in. However, a block containing an EXCEPTION clause effectively forms a subtransaction that
can be rolled back without affecting the outer transaction.
其意义是PostgreSQL的函数总是默认为一个事务,总是自动Commit或Rollback。
其实一开始没增加begin...exception...end时,PostgreSQL报错“can't begin/end transaction in pl/pgsql”,已经隐含了这层信息。只是脑子里还是延续Oracle的习惯,而画蛇添足了。
于是,修改存储过程的脚本,按最简单的法子来:
create or replace function p2(pid int, pname varchar)
returns void as $$
begin
insert into t1 values(pid, pname);
end;
$$ language plpgsql;
为验证此说法是否正确,在再次创建函数、调用函数后,增加一个回滚(事先已设置AutoCommit为false)的操作,然后再查询记录:
postgres=# \i test1.sql
CREATE FUNCTION
postgres=# select p2(1, 'abc');
----
(1 行记录)
postgres=# rollback;
WARNING: there is no transaction in progress
ROLLBACK
postgres=# select * from t1;
id | name
----+------
1 | abc
(1 行记录)
可见,这次记录已成功插入,且外部的回滚操作对其无影响。
Oracle是可以在存储过程或函数里指定Commit/Rollback的,如果没有,则外部调用者可以回滚存储过程内部的操作。
但在PostgreSQL,函数(存储过程)总是自动将其所有操作当作一个事务,外部无法对内部操作提交或回滚。
问题好像已经解决,但留有一个疑问没弄明白,为什么PostgreSQL允许在函数体中加关于事务的begin...exception...end,但结果却好像是没提交?
转载于:https://www.cnblogs.com/wggj/p/7792312.html
一、综述今天在PostgreSQL遇到一个奇怪的现象,简而言之,是想用函数(存储过程)实现插入记录,整个过程没报错但事后却没找到记录!忙活半天,才发现原因是PostgreSQL函数(存储过程)有自动COMMIT或ROLLBACK的特殊规定。二、问题重现以下用示例表和示例代码来重现该问题。create table t1 ( ID int not null primary...
对于熟悉Oracle数据库的SQL * Plus的人来说,当将其引入PostgreSQL数据库的psql时,一个潜在的惊喜可能就是psql的默认启用的autocommit 。 这篇文章概述了psql对autocommit的处理以及一些相关的细微差别 。
默认情况下, Oracle的SQL * Plus命令行工具不会自动提交DML语句 ,并且操作员必须作为事务的一部分显式提交这些语句(或退...
事务:确保一系列操作必须全部成功后,才算成功。一旦其中一个操作出错,那么会回到初始状态,哪怕前几个操作已经成功了。
比如某人要在商店使用电子货币购买100元的东西,当中至少包括两个操作:
该人账户减少 100 元。
商店账户增加100元。
支持事务的数据库管理系统就是要确保以上两个操作(整个"事务")都能完成,或一起取消,否则就会出现 100 元平白消失或出现的情况。
事务有三个命令,如下:
begin 开始事务。开始事务后,后面的操作并不会直接修改数据库,除非提交事务
commit 提交事..
PostgreSQL 正则表达式 常用函数的总结
对那些需要进行复杂数据处理的程序来说,正则表达式无疑是一个非常有用的工具。本文重点在于阐述 PostgreSQL 的一些常用正则表达式函数以及源码中的一些函数。
正则相关部分的目录结构
[root@localhost regex]# pwd
/opt/hgdb-core/src/include/regex
[root@localhost regex]# ll
total 40
-rw-r--r--. 1 postgres postgres 3490 Mar 19 19:00 regcustom.h
-rw-r--r--. 1 postgres
spring mvc 项目在执行查询功能的时候 后台报错如下:
javax.persistence.TransactionRequiredException:no transaction is in progress
............
后来找到原因是因为链接的资源有问题也就是sessionFactory所映射到配置资源链接的资源库有问题,修改之后没有问题,后来进行原因查...
public T merge(T entity) {
T returnObj = this.getJpaTemplate().merge(entity);
this.getJpaTemplate().flush();
return r
21-05-23 11:56:17.869 ERROR [taskScheduler-8 ] com.xxx.CashoutService :743 - [xxx] Process Unconfirm App Cash Record Error = {}
org.springframework.dao.InvalidDataAccessApiUsageException: no transaction is in progress; nested exception is javax.pe
\l 列出数据库
\c testdb 切换数据库
SELECT tablename FROM pg_tables WHERE tablename NOT LIKE 'pg%' AND tablename NOT LIKE 'sql_%' ORDER BY tablename; 查看所有的表列表
\d tab...
项目中虽然配置了事务,但是总感觉没起作用。
尤其是我在测试service方法时,总是报出一个异常 transaction not successfully started .
我开始以为是事务配置的问题,经过反复的检查,发现没错。
开始在网上漫无目的的搜索解决方案, 在一片帖子中看到,有人说 使用SessionFactory.getCurrentSession爆出了这个异常,解决办法...
private C c;
@Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT)
public...
可以使用 PostgreSQL 内置的 uuid-ossp 模块来生成 UUID。使用函数 uuid-ossp.uuid_generate_v4() 可以生成一个随机的 UUID。例如:
SELECT uuid-ossp.uuid_generate_v4();
这将返回一个类似于 "3f2504e-4f89-11d3-9ac-0305e82c3301" 的 UUID。