java - 关于在 jmeter 中运行的 postgres 函数测试的问题
问题描述
我正在 jmeter 中测试一个 plpgsql 函数。以下示例是复制该问题。我有一个名为 sing 的表,其定义如下
db=# \d 唱
表“schema1.sing”
柱子 | 类型 |
---|---|
ID | 大整数 |
瓦尔 | 数字 |
我的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 表的 valr 列中,如果不存在则将该值插入表中。
连接我使用 postgresql-42.2.14.jar。当加速周期为 1 秒 IE 200 请求在一秒内时,该函数会创建这样的重复值,当加速周期为 100 秒时没有问题。
db=# select * from sing;
ID | 瓦尔 |
---|---|
897 | 1095 |
898 | 1095 |
89+ | 1095 |
900 | 1095 |
901 | 1095 |
902 | 1095 |
903 | 1095 |
但实际上应该是这样的
db=# select * from sing;
ID | 瓦尔 |
---|---|
897 | 1095 |
我怎样才能避免这些类型的重复值?因为我的应用程序将有高流量可能是 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
解决方案
终于找到了解决方案,序列化的事务隔离适用于我的实际问题。查看此链接https://www.postgresql.org/docs/12/sql-set-transaction.html。默认情况下,事务是读取提交的。当我们在会话上将事务更改为序列化时,它会起作用。要使事务序列化,您可以在任何选择查询之前在会话上使用 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"
推荐阅读
- reactjs - 内容数据无法在 ckeditor4 上正确加载反应
- java - webEnvironment = RANDOM_PORT 和 webEnvironment = MOCK 之间的区别
- java - 有没有一种数据类型比 String 使用更少的 2 个字母存储空间?
- bash - 如何在另一个bash脚本编写的bash脚本中转义shell命令
- reactjs - Firestore 查询 where() 。- 返回意想不到的结果
- java - 无法在 appium 中找到元素以在 Android 应用中弹出自动警报
- python - 同一参考中的成员运算符
- heroku - Heroku 日志被 log-runtime-metrics 淹没
- syntax - Ocaml 语法与布尔值匹配
- ios - 越来越奇怪的线程1:EXC_BAD_ACCESS(代码= 1,地址= 0x9)swift中的崩溃错误