gpt4 book ai didi

ruby-on-rails-3 - Rails/ActiveRecord 悲观锁定 - 获得锁定后是否需要重新加载?

转载 作者:行者123 更新时间:2023-12-01 18:42:20 25 4
gpt4 key购买 nike

我在 Rails 中有一个交易模型,代表将从信用卡中扣除的金融交易。

创建交易后,其状态为:new。当我尝试结算费用时(这将在 DelayedJob 中发生),我将状态更新为 :pending。如果 status 不是 :new,则任何后续对 charge 的调用都将被忽略。

朴素版本(不关心并发):

# Trigger a card to be charged
def charge_transaction
return unless status == :new

self.transaction do
self.delay.settle_credit_card
self.update_attribute(:status, :pending)
end
end

# Actually do the charging (in a delayed worker)
def settle_credit_card
# ... Interact with our payment gateway
end

由于这是一个 load_balanced Web 应用程序,我想确保我们考虑并发性并且不会产生重复费用(由于并发请求)。我了解乐观锁定的好处,但在这种情况下,我不介意拥有这个关键区域,因为同时尝试收费(或以任何方式更新事务)应该是一种异常(exception)情况。

这里尝试使用悲观行级锁定

并发版本(选项 1)

# Trigger a card to be charged
def charge_transaction

# Obtain row-lock
self.with_lock do
self.reload # Reload once lock is obtained - necessary?

# Check status after lock/reload
return unless status == :new

self.delay.settle_credit_card
self.update_attribute(:status, :pending)
end
end

并发版本(选项 2)

# Trigger a card to be charged
def charge_transaction

# Begin transaction without lock
self.transaction do
self.reload(lock: true) # Reload and obtain lock

# Check status after lock/reload
return unless status == :new

self.delay.settle_credit_card
self.update_attribute(:status, :pending)
end
end

这些方法中的任何一个(或两个)都有效吗?一旦获得锁(以确保事务对象是当前的)是否需要显式重新加载,或者Rails在获得锁时会自动执行此操作吗?如果两种方法都有效,那么哪种方法更好?

非常感谢!

最佳答案

这两种方法都是有效的并且会起作用。然而,在版本 1 中,不需要重新加载 - 锁定会自动重新加载记录,因此您可以将其删除。

然后如果您检查 source code对于 with_locklock!,您会发现两个版本 100% 等效:

def lock!(lock = true)
reload(:lock => lock) if persisted?
self
end

def with_lock(lock = true)
transaction do
lock!(lock)
yield
end
end

使用 with_lock 是最简单也是首选的方式:

# Obtain row-lock
with_lock do
# Check status after lock/reload
return unless status == :new

delay.settle_credit_card
update_attribute(:status, :pending)
end

(注意:您可以安全地从方法调用中删除 self)

关于ruby-on-rails-3 - Rails/ActiveRecord 悲观锁定 - 获得锁定后是否需要重新加载?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15694326/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com