【发布时间】:2015-07-03 00:41:37
【问题描述】:
我正在使用 aasm_state gem 和 sidekiq。这是customer.rb对于aasm_state的定义的样子:
aasm do
state :closed, initial: true
state :open
state :claimed
event :open do
transitions from: :closed, to: :open
end
event :claim do
transitions from: [:open, :closed], to: :claimed
end
event :close do
transitions from: [:open, :claimed], to: :closed
before do
self.user_id = nil
end
end
end
然后我在customer.rb中也有:
def properly_close
if closed? && user_id
Rails.logger.info "Bad customer state with customer_id: #{id} at #{Time.now} and the last message was at #{messages.last.created_at}. Aasm_state_was: #{aasm_state_was}"
self.user_id = nil
end
end
只要 aasm_state == '已关闭',客户上就不应该有 user_id。但是,它仍然经常发生。我认为这与sidekiq 并行工作有关,但我不确定。即使我有两种方法来确保 user_id = nil(在 before do 和 proper_close 中),它仍然最终被设置为 aasm_state == 'closed' && user_id
这怎么可能?我如何弄清楚它是如何发生的?
【问题讨论】:
-
表中有 lock_version 列吗?尝试通过添加此列将其添加到打开内置乐观锁定机制。至少它可能有助于找出对该表的更多并发访问。
-
我会试试看的。但是,只要考虑一下 activerecord/sidekiq 的工作原理,如果每个作业的单个值永远不会是 aasm_state = closed && user_id not nil,我很难理解并发性是如何成为问题的。
-
你是用
update_attribute直接设置状态吗?update_attribute将绕过验证和回调。
标签: ruby-on-rails activerecord sidekiq