postgresql - 如何为 postgres 配置休眠隔离级别
问题描述
我ErrorCase
在 postgres 数据库中有一个表。此表有一个case_id
数据类型为文本的字段。它的值由格式生成:yymmdd_xxxx
. yymmdd 是记录插入数据库的日期,xxxx 是该日期的记录数。
例如,2019/08/01 的第 3 个错误案例将具有case_id
= 190801_0003。在 08/04,如果还有一个案例,case_id
它将是 190804_0001,然后继续。
我已经在数据库中使用触发器为该字段生成值:
DECLARE
total integer;
BEGIN
SELECT (COUNT(*) + 1) INTO total FROM public.ErrorCase WHERE create_at = current_date;
IF (NEW.case_id is null) THEN
NEW.case_id = to_char(current_timestamp, 'YYMMDD_') || trim(to_char(total, '0000'));
END IF;
RETURN NEW;
END
在 Spring Project 中,我为 jpa/hibernates 配置应用程序属性:
datasource:
type: com.zaxxer.hikari.HikariDataSource
url: jdbc:postgresql://localhost:5432/table_name
username: postgres
password: postgres
hikari:
poolName: Hikari
auto-commit: false
jpa:
database-platform: io.github.jhipster.domain.util.FixedPostgreSQL82Dialect
database: POSTGRESQL
show-sql: true
properties:
hibernate.id.new_generator_mappings: true
hibernate.connection.provider_disables_autocommit: true
hibernate.cache.use_second_level_cache: true
hibernate.cache.use_query_cache: false
hibernate.generate_statistics: true
目前,它会正确生成 case_id。
但是,当几乎同时插入许多记录时,它会case_id
为两条记录生成相同的记录。我想原因是因为隔离级别。当第一个事务尚未提交时,第二个事务执行 SELECT 查询以构建 case_id。因此,SELECT 查询的结果不包括第一次查询的记录(因为它还没有提交)。因此,第二个case_id
与第一个具有相同的结果。
请建议我解决此问题的任何解决方案,哪种隔离级别适合这种情况???
解决方案
“ yymmdd 是记录插入数据库的日期,xxxx 是该日期的记录数” - 没有冒犯,但这是一个可怕的设计。
您应该有两个单独的列,一date
列和一integer
列。如果要在插入期间增加计数器,请将该日期列设为主键并使用insert on conflict
. 您可以摆脱这种效率极低的触发器,更重要的是,即使已提交读取,并发修改也将是安全的。
就像是:
create table error_case
(
error_date date not null primary key,
counter integer not null default 1
);
然后使用以下内容插入行:
insert into error_case (error_date)
values (date '2019-08-01')
on conflict (error_date) do update
set counter = counter + 1;
并发插入不需要触发器并且是安全的。
如果您确实需要一个文本列作为“案例 ID”,请创建一个返回该格式的视图:
create view v_error_case
as
select concat(to_char(error_date, 'yymmdd'), '_', to_char(counter, '0000')) as case_id,
... other columns
from error_case;
推荐阅读
- sql - 在 BigQuery 中查询双嵌套数组
- r - 在特定条件下通过列表的特定函数(for循环和/或函数)
- java - 在do-while循环中退出程序而没有其他消息 - Java
- python - 有没有更好/更快的方法来实现这样的多个 if 语句?
- python - 用它们的总和替换特定的行
- reactjs - 在 Web 组件中设置 React 组件的样式
- amazon-web-services - lambda内的Dynamodb连接超时
- docker - GitHub Actions 忽略/覆盖 Docker 容器的入口点
- bash - 使用 dd 和重定向分块处理标准输入的 bash 脚本
- java - 与 Ignite 集群建立客户端连接导致服务器上出现 OutOfMemoryError