作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我试图悲观地锁定表 (Postgres) 的一个子集以进行条件插入,并且我花了很长时间找到有效的语法。这基本上是我想要做的:
ActiveRecord::Base.transaction do
if consumer.purchases.lock.sum(&:amount) < some_threshold
consumer.purchases.create!(amount: amount)
end
end
consumer.purchases.lock.to_sql
结果
SELECT "purchases".* FROM "purchases" WHERE "purchases"."consumer_id" = ? FOR UPDATE
正如我所料,但是
.create!
导致查询生成器删除
FOR UPDATE
锁。
# Process 1
ActiveRecord::Base.transaction do
consumer.purchases.tap{ |p| p.lock! }.create!(amount: amount)
sleep 20
end
# Process 2
ActiveRecord::Base.transaction do
consumer.purchases.tap{ |p| p.lock! }.create!(amount: amount)
# Should wait but doesn't
end
ActiveRecord::Base.transaction do
purchases = Consumer.find(3).purchases
purchases.lock
purchase = purchases.new(amount: amount)
purchase.save!
sleep 20
end
... Other process doesn't wait...
# DOES WORK!
# Process 1
ActiveRecord::Base.transaction do
purchases = Consumer.where(id: 3).first.purchases
purchases.each(&:lock!)
purchase = purchases.new(amount: amount)
purchase.save!
sleep 20
end
# Process 2
ActiveRecord::Base.transaction do
purchases = Consumer.where(id: 3).first.purchases
purchases.each(&:lock!)
purchase = purchases.new(amount: amount)
purchase.save!
# waits as it should
end
BEGIN;
SELECT * FROM purchases WHERE consumer_id = 3 FOR UPDATE;
SELECT pg_sleep(30);
INSERT INTO purchases (name, amount) VALUES ('shouldBlock30Seconds', '1000');
END;
BEGIN;
SELECT * FROM purchases WHERE consumer_id = 3 FOR UPDATE;
INSERT INTO purchases (name, amount) VALUES ('shouldWait30Seconds', '1000');
END;
BEGIN;
SELECT * FROM purchases WHERE consumer_id = 24839992 FOR UPDATE;
INSERT INTO purchases (name, amount) VALUES ('shouldInsertImmediately', '1000');
END;
shouldInsertImmediately
立即插入,
shouldBlock30Seconds
30 秒后插入,并且
shouldWait30Seconds
之后立即插入。
最佳答案
purchases.lock
不锁定任何内容,它只返回一个新关系,该关系将在获取时锁定记录。
尝试强制选择:purchases.lock.to_a
关于ruby-on-rails - 如何悲观地锁定Rails中的多行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60193089/
我正在编写一个 Web 应用程序,两个不同的用户可以在其中更新事物列表,例如待办事项列表。我已经意识到,乐观锁定机制效果最好,因为我不希望出现高争用情况。 我一直在查看事务隔离级别,现在我有点困惑。看
我是一名优秀的程序员,十分优秀!