我必须为使用Postgres for database的非常高流量的Web应用程序编写SQL事务。控制并发读取然后更新然后在Postgres中写入事务
我的问题是如何控制READ THEN UPDATE THEN WRITE事务的并发性,如果两个用户同时进行该事务?
对于高流量的Web应用程序,最佳做法是什么?任何帮助/建议将非常感激。
在此先感谢。
我必须为使用Postgres for database的非常高流量的Web应用程序编写SQL事务。控制并发读取然后更新然后在Postgres中写入事务
我的问题是如何控制READ THEN UPDATE THEN WRITE事务的并发性,如果两个用户同时进行该事务?
对于高流量的Web应用程序,最佳做法是什么?任何帮助/建议将非常感激。
在此先感谢。
解释性说明:我假设您的意思是read-modify-write工作负载,并且“READ THEN UPDATE THEN WRITE”的大写字母并不意味着表示某些特殊事务选项SQL语法来自我不熟悉的产品。
如果你的web应用正在做读 - 修改 - 写高并发和流量的循环,那么你就不能使用传统的行锁定:
BEGIN
SELECT primarykey, col1 FROM thetable WHERE ... FOR UPDATE
UPDATE blah SET col1 ... WHERE primarykey ...
COMMIT
因为用户“思考时间”和网络延迟可能是无限的。大多数连接将在“应用程序中的过程”阶段中停留无限期。每个等待会话意味着一个开放的空闲事务,这意味着有限的数据库资源,如连接限制和内存消耗。
传统的,完善的解决方案是使用optimistic concurrency control,有时误导性地称为乐观锁定。一些ORM在本地支持。如果您直接使用SQL或通过不支持的框架,那么实现它就很容易。其原理是,你的逻辑流程大致如下:
BEGIN READ ONLY TRANSACTION
SELECT primarykey, col1, row_version FROM thetable WHERE ...
COMMIT
BEGIN
UPDATE blah SET col1 ..., row_version = row_version + 1 WHERE primarykey ... AND row_version = 'prev_row_version'
UPDATE
使用影响由数据库中UPDATE
响应
WHERE
条款不相符,暗示别人更新的行,因为我们SELECT
编它。回到开始并重新开始。COMMIT
并告诉用户一切正常。框架如Hibernate通过注释列作为行版本的自动支持这一点。
乐观并发控制可以与传统的锁定和适当的数据库触发器进行互操作。参见例如the sample trigger I wrote for Hibernate inter-operation。
https://wiki.postgresql.org/wiki/Performance_Optimization –
你能更具体的了解,究竟是什么,您可以通过“读,然后更新,然后写上”是什么意思?你的意思是通过应用程序进行读 - 修改 - 写吗? –
嗨克雷格,是我的意思是通过应用程序中的读 - 修改 - 写。 – John