Pak*_*Lui 4 postgresql concurrency transaction isolation-level
如何使用基于交易的策略来确保同一地点在同一天不能被多次预订?
有人向我建议,每个隔离级别都会有所不同。你能为他们每个人添加一个例子吗?( read committed
,repeatable read
和serializable
)。我想了解他们中的每一个人。
以下是表格和测试数据:
CREATE TABLE place (
place_id INT PRIMARY KEY,
Name CHARACTER VARYING(50) NOT NULL,
Type CHARACTER VARYING(50) NOT NULL
);
CREATE TABLE visit (
visit_id SERIAL PRIMARY KEY,
place_id INT NOT NULL,
place_dt TIMESTAMP NOT NULL,
FOREIGN KEY (place_id) REFERENCES place(place_id)
);
INSERT INTO place(place_id, Name, Type
) VALUES
(1, 'Denali', 'mountain'),
(2, 'Brindley', 'mountain'),
(3, 'St. Louis Cathedral', 'church')
;
INSERT INTO visit(place_id, place_dt
) VALUES
(1, '2019-01-02 10:00'),
(2, '2019-01-02 11:00'),
(3, '2019-01-03 14:09')
;
Run Code Online (Sandbox Code Playgroud)
我想要的是,对于每个隔离级别,寻找一种基于事务的策略,以确保同一位置在同一天不能被预订多次。
鉴于在这种情况下,策略可能对于各种隔离级别都是最佳的。
劳伦斯说的。请注意,Postgres 跨事务隔离边界检查(必须检查)是否存在唯一违规(由重复进入UNIQUE
索引引发的异常)。这些检查是“绝对的”。手册中“索引唯一性检查”
一章中的详细信息。
但是使用这个优化的等效解决方案,同时使用它:
CREATE UNIQUE INDEX ON visit (place_id, cast(place_dt AS date));
Run Code Online (Sandbox Code Playgroud)
place_id
是integer
(4 个字节)。
date_trunc()
返回timestamp
用于timestamp
输入(8个字节)。
date
只占用4个字节。
空间通常以 8 字节的倍数分配。
一个索引(integer, timestamp)
有效地占用每个索引元组 28 个字节。
一个索引(integer, date)
有效地占用每个索引元组 20 个字节。所以另一个是大 40% 没有增益。
更多细节:
旁白:索引还有助于 FK 约束的性能visit (place_id)
- 当您place_id
放在首位时。
为此,您只需visit
在唯一索引的形状上设置约束:
CREATE UNIQUE INDEX ON visit (place_id, date_trunc('day', place_dt));
Run Code Online (Sandbox Code Playgroud)
无论隔离级别如何,这都将保证唯一性。
归档时间: |
|
查看次数: |
250 次 |
最近记录: |