我想创建一个电影预订功能。我有一个列来存储当天预订的门票数量。当有人注册时,我在计数上加1,当有人取消时,我减1。但是如果两个人同时注册会发生什么?我不确定总数是否准确。我使用Rails 5和MySQL。在这种情况下,我应该使用什么技术?
dm7nw8vv1#
Rails处理此问题的常用方法是使用counter cache方法来递增或递减列。通常情况下,您会在belongs_to上使用:counter_cache选项:
belongs_to
:counter_cache
通过使用CounterCache::ClassMethods#increment_counter和CounterCache::ClassMethods#decrement_counter缓存关联类上所属对象的数量。计数器缓存在创建该类的对象时递增,在销毁该类的对象时递减。这需要在关联类(例如Post类)上使用名为#{table_name}_count的列(例如comments_count,用于所属的Comment类)-即在关联类上创建#{table_name}_count的迁移(这样Post.comments_count将返回缓存的计数,请参见下面的注解)。您还可以通过向此选项提供列名而不是真/假值来指定自定义计数器缓存列(例如,counter_cache: :my_custom_counter)。指定计数器缓存将使用attr_readonly将其添加到该模型的只读属性列表中。计数器缓存方法在数据库中直接使用UPDATE s,如下所示:
CounterCache::ClassMethods#increment_counter
CounterCache::ClassMethods#decrement_counter
Post
#{table_name}_count
comments_count
Comment
Post.comments_count
counter_cache: :my_custom_counter
attr_readonly
UPDATE
update movies set counter_column = coalesce(counter_column, 0) + 1 where id = ...
所以计数器维护应该是原子的。在注册过程中,您可能会同时进行几件事,因此您需要将整个过程 Package 在transaction中:
Movie.transaction do # Register user # Track payment # Whatever else is going on... end
1条答案
按热度按时间dm7nw8vv1#
Rails处理此问题的常用方法是使用counter cache方法来递增或递减列。通常情况下,您会在
belongs_to
上使用:counter_cache
选项::counter_cache
通过使用
CounterCache::ClassMethods#increment_counter
和CounterCache::ClassMethods#decrement_counter
缓存关联类上所属对象的数量。计数器缓存在创建该类的对象时递增,在销毁该类的对象时递减。这需要在关联类(例如Post
类)上使用名为#{table_name}_count
的列(例如comments_count
,用于所属的Comment
类)-即在关联类上创建#{table_name}_count
的迁移(这样Post.comments_count
将返回缓存的计数,请参见下面的注解)。您还可以通过向此选项提供列名而不是真/假值来指定自定义计数器缓存列(例如,counter_cache: :my_custom_counter
)。指定计数器缓存将使用attr_readonly
将其添加到该模型的只读属性列表中。计数器缓存方法在数据库中直接使用
UPDATE
s,如下所示:所以计数器维护应该是原子的。
在注册过程中,您可能会同时进行几件事,因此您需要将整个过程 Package 在transaction中: