在Rails应用程序中,我需要一个独特的,顺序(无间隙)整数的源,以用作序列号。它必须是持久的并允许并发访问。
数据库自动增量是不够的,因为大多数人都不保证“无间隙”属性。
在直接SQL中我只想创建一个单行表并说出(在PostgreSQL中)类似于:
update sequence set value = value + 1 returning value
这显然是SQL世界的标准做法。参考文献存在。
在ActiveRecord中,我轻松地为模型创建了一个模型,并在文档中找到了.increment!
和.increment_counter
。但我无法弄清楚如何原子地检索增量值。锁和交易似乎没有帮助。
答案 0 :(得分:2)
由于update ... returning
的作用类似于输出目的,因此可以使用find_by_sql
来更新并在一次操作中获取更新的值。
class SequenceNumber < ActiveRecord::Base
attr_accessible :tag, :value
validates :tag, :uniqueness => true
def self.get_next(tag)
find_by_sql("update sequence_numbers
set value = value + 1
where tag = '#{tag}'
returning value").first.value
end
end
剩下的问题是这完全不可移植,因为returning
是pgsql扩展。也许ActiveRecord开发人员会注意到这一点。
答案 1 :(得分:0)
如果你想使用redis(也许你已经是因为Resque或Sidekiq),你可以对一个键执行INCR
,这是原子并返回新值。