Art*_*hur 5 postgresql concurrency
我有一个intervals
表,用于存储变量的start
日期和end
日期variable_id
(四列:)id, start, end, variable_id
。
客户端计算一个变量的新间隔并将它们存储在该表中。为了保持一致性(对于variable_id
我不想间隔重叠),客户端首先检查(select
),我们有什么样的时间间隔,然后insert
,delete
和/或update
相应的(或者什么都不做)。
如果两个客户同时这样做,当然会有我插入重叠间隔的风险,这是我不想要的。
其实我的问题很简单:我该怎么办?
似乎 aSELECT .. FOR UPDATE
不起作用,因为这会锁定现有的行,这对我来说还不够,因为可能会插入行。我宁愿需要“ SELECT * FROM intervals WHERE variable_id = 1234
”的结果在某种程度上是“安全的”。
我已经实现了一个使用SERIALIZABLE
事务的解决方案。结果是,如果两个客户端输入这个 select/update-delete-insert 事务,一个将失败(could not serialize access due to read/write dependencies among transactions
或could not serialize access due to concurrent update
),在这种情况下,我只需要再次运行我的 select/update-delete-insert 逻辑以尝试插入更合适的间隔.
这里的问题是serializable
事务似乎锁定了整个表。但是如果一个客户端想要更新变量1234的间隔,而另一个客户端想要更新变量4321的,应该没有问题,两个事务应该能够愉快地运行。
我不是 SQL 专家,甚至无法确定这是一个简单的经典 sql 问题还是一个难题。
一些评论:
intervals
表上,我们有变量的值的时间间隔。但是,我认为这不会干扰上述问题。关于 SERIALIZABLE 事务,请务必注意本节底部附近的“以获得最佳性能”提示:http : //www.postgresql.org/docs/9.1/interactive/transaction-iso.html#XACT-SERIALIZABLE 这些可以显着降低回滚率。
也就是说,并不是为了阻止使用 SERIALIZABLE 事务隔离级别,您所描述的听起来正是 EXCLUSION CONSTRAINT 旨在解决的那种问题。在存在强制执行业务规则的声明性约束的情况下,这几乎总是比使用命令式编码(在触发器或应用程序代码中)更好。
http://www.postgresql.org/docs/9.1/static/ddl-constraints.html#DDL-CONSTRAINTS-EXCLUSION
http://www.postgresql.org/docs/9.1/static/sql-createtable.html#SQL-CREATETABLE-EXCLUDE
要将此功能与日期一起使用,您目前需要使用 TEMPORAL 模块:
http://pgfoundry.org/projects/temporal/
当您迁移到 PostgreSQL 9.2 版(预计将于今年夏天发布)时,您可能希望将 TEMPORAL 列迁移到 RANGE。9.2 RANGE 特性、TEMPORAL 数据类型和 EXCLUSION CONSTRAINT 特性都是 Jeff Davis 解决问题中提出的问题的所有工作。它们旨在协同工作。
完全披露:9.1 中的 SERIALIZABLE 事务行为是由我和麻省理工学院的 Dan RK Ports 开发的。
归档时间: |
|
查看次数: |
2481 次 |
最近记录: |