我看到的是一次失败的重试 first_or_initialize
这“显然是不可能的”。不知何故,即使允许多次重试,也会发生这种情况。
该表包含列 id
(整数主键), uuid
(二进制)和 item_id
(整数)。两者 uuid
以及 item_id
有唯一的索引。
该方法应检索该项的uuid,如果该项不存在,则应创建一个uuid:
def self.get_uuid_for(item)
Retryable.retryable(tries: MAX_RETRIES, on: [ActiveRecord::RecordNotUnique], sleep: 0) do
ActiveRecord::Base.transaction(requires_new: true) do
item_uuid = where(item_id: item).first_or_initialize do |item_uuid|
item_uuid.uuid = SecureRandom.uuid
item_uuid.save!
end
item_uuid.uuid
end
end
end
在本地运行时,它可以工作:
无现有条目(选择、插入)
使用现有条目(选择)
具有竞争事务(选择、插入、回滚、选择)
不幸的是,在某个时刻,错误收集器收到:
ActiveRecord::RecordNotUnique: Mysql2::Error: Duplicate entry '22573725' for key 'index_item_uuids_on_item_id'
我很难解释。最大重试次数恰好是100次,因此即使该关联一直被创建和删除,所有这些重试都有可能失败。这也不是并发事务需要很长时间的情况,因为在这种情况下 item_uuid.save!
挂着等待锁。
我错过了什么场景?
数据库是mysql/aws aurora 5.6。隔离级别为 REPEATABLE-READ
.
暂无答案!
目前还没有任何答案,快来回答吧!