我正在jmeter中测试一个plpgsql函数。下面的示例将复制该问题。我有一个名为sing的表,其定义如下
db=#\d唱
表“schema1.sing”
列类型原始数值
我的plpgsql函数如下
create or replace function schema1.insissue(val text) returns text as $$
declare
_p text;_h text;
ids text[];
valid numeric := functiontochangetoid(val); // a sample function to change value into id.
slid bigint:= nextval('rep_s'); // sequence value
dup text := null;
begin
select array_agg(id) from sing where valr = valid into ids;
raise notice 'ids %',ids;
if coalesce(array_upper(ids,1),0) > 0 then
dup = 'FAIL';
end if;
raise notice 'dup %',dup;
if dup is null then
insert into sing values (slid,valid);
return 'SUCCESS'|| slid;
end if;
return 'FAIL';
exception
when others then
get stacked diagnostics
_p := pg_exception_context,_h := pg_exception_hint;
raise notice 'sqlerrm >> :%',sqlerrm;
raise notice 'position >> :%',_p;
raise notice 'hint >> :%',_h;
return 'FAIL';
end;
$$ language plpgsql;
只需在我的函数中检查值是否存在于sing table的valr列中,如果不存在,则将值插入表中。
现在我的jmeter配置
为了连接,我使用postgresql-42.2.14.jar。当爬升周期为1秒,即1秒内请求200次时,函数会创建类似这样的重复值,当爬升周期为100秒时,不会出现问题。
db=#从sing中选择*;
IDVALR8971095810959001095899109590110990210959031095
但事实上应该是这样
db=#从sing中选择*;
idvalr8971095号
如何避免这些类型的重复值?因为我的应用程序将有高流量,可能是100个电话在第二也我不能使“valr”列的主键。因为它包含其他类型的值。
我的postgres版本
db=# select version();
version
------------------------------------------------------------------------------------------------------------------
PostgreSQL 12.3 (Debian 12.3-1.pgdg100+1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 8.3.0-6) 8.3.0, 64-bit
1条答案
按热度按时间k10s72fa1#
最后找到了解决方案,事务隔离序列化解决了我的实际问题。 checkout 此链接https://www.postgresql.org/docs/12/sql-set-transaction.html. 默认情况下,事务是读取提交的。当我们在会话中将事务更改为序列化时,它可以工作。要使事务序列化,可以在任何select查询之前对会话使用set命令
它不能只在postgresql的函数或过程中为会话执行。我们可以在程序中使用set,但会出现这样的错误