我正在运行一个使用 rails 3.2.3 的应用程序,它位于使用 tinyTDS 进行连接的 MS SQL Sever 实例之上。该应用程序是多线程的,使用独角兽有 4 个进程。问题是应用程序使用数据库中的一个字段来存储一个需要递增的数字,以便为每个请求分配一个唯一的帐号。当我在本地运行应用程序时没有问题,因为它不是多线程的。
当我使用 unicorn 在我们的暂存环境中运行时,当我使用多个并发请求访问应用程序时,每 10 个左右的请求中就有 1 个返回一个重复的卡号。我尝试了以下方法。
旧代码
row = CardValue.find_by_name("next_card_number") \ or raise "Missing next_card_number row in card_values table"
next_card_number = row.value
row.value = (next_card_number.to_i + 1).to_s
row.save!
return next_card_number
旧代码 + 事务
CardValue.transaction do
row = CardValue.find_by_name("next_card_number") \ or raise "Missing next_card_number row in card_values table"
next_card_number = row.value
row.value = (next_card_number.to_i + 1).to_s
row.save!
return next_card_number
end
结果:没有效果
旧代码 + with_lock
CardValue.with_lock do
row = CardValue.find_by_name("next_card_number") \ or raise "Missing next_card_number row in card_values table"
next_card_number = row.value
row.value = (next_card_number.to_i + 1).to_s
row.save!
return next_card_number
end
结果: with_lock 未定义的错误
旧代码 + with_lock
CardValue.transaction do
lock!
row = CardValue.find_by_name("next_card_number") \ or raise "Missing next_card_number row in card_values table"
next_card_number = row.value
row.value = (next_card_number.to_i + 1).to_s
row.save!
return next_card_number
end
结果:锁未定义的错误