关于jmeter中postgres函数测试运行的问题

w8biq8rn  于 2021-06-29  发布在  Java
关注(0)|答案(1)|浏览(462)

我正在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
k10s72fa

k10s72fa1#

最后找到了解决方案,事务隔离序列化解决了我的实际问题。 checkout 此链接https://www.postgresql.org/docs/12/sql-set-transaction.html. 默认情况下,事务是读取提交的。当我们在会话中将事务更改为序列化时,它可以工作。要使事务序列化,可以在任何select查询之前对会话使用set命令

SET transaction isolation level serializable;

它不能只在postgresql的函数或过程中为会话执行。我们可以在程序中使用set,但会出现这样的错误

NOTICE:  sqlerrm >> :SET TRANSACTION ISOLATION LEVEL must be called before any query
NOTICE:  position >> :SQL statement "SET transaction isolation level serializable"

相关问题