我有一个场景,我认为我需要针对所有活动(读取和写入)锁定表。我正在使用 Propel 1.6.x 并打算编写一个小的额外库来处理锁定。
我的用例是一个版本表,它的主键是(id、creator、version)。列对 (id, creator) 实际上是另一个表上的 PK。插入新行时,会在 PHP 代码中读取 MAX(version),然后将其插入行类以供以后保存。在最大值和保存之间,存在潜在的竞争条件,其中另一个进程可以获得相同的最大值,然后当然其中一个插入会由于非唯一性而失败。
为了避免需要锁,我宁愿使用子选择进行保存,例如:
INSERT INTO
test_model_test_organiser_versionable
(id, creator, version)
VALUES (
3,
1,
(
SELECT COALESCE(MAX(version), 1)
FROM test_model_test_organiser_versionable
WHERE id = 3
AND creator = 1
)
);
然而这在 Propel 中不受支持,如果我通过 PDO 来实现,我将无法(afaik)发现赋予复合 PK 的“版本”部分的值。
现在,我可以有一个额外的自动递增列,因为可以在插入后读取自动递增的值以查找行,因此我可以在 Propel 中进行重新选择。但是,如果我能提供帮助,我想避免多余的专栏——在我看来,这似乎不够优雅。
所以......我的感觉是,将 max & save 调用封装在一个锁中是要走的路。这将不得不锁定整个表 IMO,并防止读取和写入(否则后续的最大调用将不会等待,因此会导致非唯一性再次失败)。
我需要它与 Propel 支持的所有平台一起工作,所以 - 除非我应该采取更好的方法 - 是否有一个 PHP 库可以对任何 PDO 数据库进行这种锁定?如果没有,我可以自己做 - 但如果其他人针对各种 dbs 完成了测试驴工作,那就太好了(设置 MSSQL Server? - 不,谢谢 :)