Active Recordの話です。
create_or_find_byの実装はcreateしてみてユニーク制約に引っかかったらfind_byしてみるなので、ふつうに考えるとfind_byは成功しそうに見えます。
def create_or_find_by(attributes, &block) transaction(requires_new: true) { create(attributes, &block) } rescue ActiveRecord::RecordNotUnique find_by!(attributes) end
ですが、以下のスクリプトを実行するとcreate_or_find_byはcreateがRecordNotUnique例外を吐いたあと、find_byもRecordNotFound例外を吐いてレコードを見つけられずに死にます。
ちょっと今から会食なので原理は帰ってから書き足しますしばしお待ちを🙇♂️
これ時間あったら続き書きたいけどとりいそぎ説明すると、REPEATABLE READでファントムリードを防いでることを利用して失敗させてるからREAD COMMITTEDにしてファントムリードを許すかSERIALIZABLEにするかLocking Readして別トランザクションの更新をブロックすると失敗を防げます。 https://t.co/v4LBhwDWeR
— Ryuta Kamizono (@kamipo) December 20, 2020
# frozen_string_literal: true require "bundler/inline" gemfile(true) do source "https://rubygems.org" git_source(:github) { |repo| "https://github.com/#{repo}.git" } gem "activerecord", "6.1.0" gem "mysql2" end require "active_record" require "logger" ActiveRecord::Base.establish_connection(adapter: "mysql2", database: "test", username: "root") ActiveRecord::Base.logger = Logger.new(STDOUT) ActiveRecord::Schema.define do create_table :users, force: true do |t| t.string :name, index: { unique: true } end end class User < ActiveRecord::Base end t = Thread.new do sleep 0.1 User.create!(name: "foo") end User.transaction do User.find_by!(name: "foo") rescue ActiveRecord::RecordNotFound puts 'User<name: "foo"> not found' sleep 0.2 User.create_or_find_by!(name: "foo").tap do puts 'User<name: "foo"> has found or created' end end t.join
% ruby foo.rb Fetching gem metadata from https://rubygems.org/......... Resolving dependencies... Using concurrent-ruby 1.1.7 Using i18n 1.8.5 Using minitest 5.14.2 Using tzinfo 2.0.3 Using zeitwerk 2.4.2 Using activesupport 6.1.0 Using activemodel 6.1.0 Using activerecord 6.1.0 Using bundler 2.1.4 Using mysql2 0.5.3 -- create_table(:users, {:force=>true}) D, [2020-12-16T18:55:22.915787 #49715] DEBUG -- : (12.2ms) DROP TABLE IF EXISTS `users` D, [2020-12-16T18:55:22.954341 #49715] DEBUG -- : (37.5ms) CREATE TABLE `users` (`id` bigint NOT NULL AUTO_INCREMENT PRIMARY KEY, `name` varchar(255), UNIQUE INDEX `index_users_on_name` (`name`)) -> 0.0754s D, [2020-12-16T18:55:23.132151 #49715] DEBUG -- : ActiveRecord::InternalMetadata Load (0.7ms) SELECT `ar_internal_metadata`.* FROM `ar_internal_metadata` WHERE `ar_internal_metadata`.`key` = 'environment' LIMIT 1 D, [2020-12-16T18:55:23.147310 #49715] DEBUG -- : TRANSACTION (0.3ms) BEGIN D, [2020-12-16T18:55:23.151778 #49715] DEBUG -- : User Load (0.8ms) SELECT `users`.* FROM `users` WHERE `users`.`name` = 'foo' LIMIT 1 User<name: "foo"> not found D, [2020-12-16T18:55:23.283424 #49715] DEBUG -- : TRANSACTION (0.3ms) BEGIN D, [2020-12-16T18:55:23.287159 #49715] DEBUG -- : User Create (3.5ms) INSERT INTO `users` (`name`) VALUES ('foo') D, [2020-12-16T18:55:23.290553 #49715] DEBUG -- : TRANSACTION (2.8ms) COMMIT D, [2020-12-16T18:55:23.359126 #49715] DEBUG -- : TRANSACTION (0.3ms) SAVEPOINT active_record_1 D, [2020-12-16T18:55:23.360585 #49715] DEBUG -- : User Create (1.2ms) INSERT INTO `users` (`name`) VALUES ('foo') D, [2020-12-16T18:55:23.361383 #49715] DEBUG -- : TRANSACTION (0.3ms) ROLLBACK TO SAVEPOINT active_record_1 D, [2020-12-16T18:55:23.362859 #49715] DEBUG -- : User Load (0.5ms) SELECT `users`.* FROM `users` WHERE `users`.`name` = 'foo' LIMIT 1 D, [2020-12-16T18:55:23.363994 #49715] DEBUG -- : TRANSACTION (0.5ms) ROLLBACK Traceback (most recent call last): 12: from foo.rb:34:in `<main>' 11: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/transactions.rb:209:in `transaction' 10: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/connection_adapters/abstract/database_statements.rb:320:in `transaction' 9: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/connection_adapters/abstract/transaction.rb:308:in `within_new_transaction' 8: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activesupport-6.1.0/lib/active_support/concurrency/load_interlock_aware_monitor.rb:21:in `synchronize' 7: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activesupport-6.1.0/lib/active_support/concurrency/load_interlock_aware_monitor.rb:21:in `handle_interrupt' 6: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activesupport-6.1.0/lib/active_support/concurrency/load_interlock_aware_monitor.rb:25:in `block in synchronize' 5: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activesupport-6.1.0/lib/active_support/concurrency/load_interlock_aware_monitor.rb:25:in `handle_interrupt' 4: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activesupport-6.1.0/lib/active_support/concurrency/load_interlock_aware_monitor.rb:26:in `block (2 levels) in synchronize' 3: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/connection_adapters/abstract/transaction.rb:310:in `block in within_new_transaction' 2: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/connection_adapters/abstract/database_statements.rb:320:in `block in transaction' 1: from foo.rb:35:in `block in <main>' /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/core.rb:366:in `find_by!': Couldn't find User (ActiveRecord::RecordNotFound) 87: from foo.rb:34:in `<main>' 86: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/transactions.rb:209:in `transaction' 85: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/connection_adapters/abstract/database_statements.rb:320:in `transaction' 84: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/connection_adapters/abstract/transaction.rb:308:in `within_new_transaction' 83: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activesupport-6.1.0/lib/active_support/concurrency/load_interlock_aware_monitor.rb:21:in `synchronize' 82: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activesupport-6.1.0/lib/active_support/concurrency/load_interlock_aware_monitor.rb:21:in `handle_interrupt' 81: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activesupport-6.1.0/lib/active_support/concurrency/load_interlock_aware_monitor.rb:25:in `block in synchronize' 80: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activesupport-6.1.0/lib/active_support/concurrency/load_interlock_aware_monitor.rb:25:in `handle_interrupt' 79: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activesupport-6.1.0/lib/active_support/concurrency/load_interlock_aware_monitor.rb:26:in `block (2 levels) in synchronize' 78: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/connection_adapters/abstract/transaction.rb:310:in `block in within_new_transaction' 77: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/connection_adapters/abstract/database_statements.rb:320:in `block in transaction' 76: from foo.rb:35:in `block in <main>' 75: from foo.rb:41:in `rescue in block in <main>' 74: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/querying.rb:22:in `create_or_find_by!' 73: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/relation.rb:218:in `create_or_find_by!' 72: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/relation/delegation.rb:108:in `method_missing' 71: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/relation.rb:406:in `scoping' 70: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/relation.rb:811:in `_scoping' 69: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/relation.rb:406:in `block in scoping' 68: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/relation/delegation.rb:108:in `block in method_missing' 67: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/relation/delegation.rb:108:in `public_send' 66: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/transactions.rb:209:in `transaction' 65: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/connection_adapters/abstract/database_statements.rb:320:in `transaction' 64: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/connection_adapters/abstract/transaction.rb:308:in `within_new_transaction' 63: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activesupport-6.1.0/lib/active_support/concurrency/load_interlock_aware_monitor.rb:21:in `synchronize' 62: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activesupport-6.1.0/lib/active_support/concurrency/load_interlock_aware_monitor.rb:21:in `handle_interrupt' 61: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activesupport-6.1.0/lib/active_support/concurrency/load_interlock_aware_monitor.rb:25:in `block in synchronize' 60: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activesupport-6.1.0/lib/active_support/concurrency/load_interlock_aware_monitor.rb:25:in `handle_interrupt' 59: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activesupport-6.1.0/lib/active_support/concurrency/load_interlock_aware_monitor.rb:26:in `block (2 levels) in synchronize' 58: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/connection_adapters/abstract/transaction.rb:310:in `block in within_new_transaction' 57: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/connection_adapters/abstract/database_statements.rb:320:in `block in transaction' 56: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/relation.rb:218:in `block in create_or_find_by!' 55: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/relation.rb:114:in `create!' 54: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/relation.rb:406:in `scoping' 53: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/relation.rb:811:in `_scoping' 52: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/relation.rb:406:in `block in scoping' 51: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/relation.rb:114:in `block in create!' 50: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/relation.rb:806:in `_create!' 49: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/persistence.rb:55:in `create!' 48: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/suppressor.rb:48:in `save!' 47: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/transactions.rb:300:in `save!' 46: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/transactions.rb:348:in `with_transaction_returning_status' 45: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/connection_adapters/abstract/database_statements.rb:318:in `transaction' 44: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/transactions.rb:352:in `block in with_transaction_returning_status' 43: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/transactions.rb:300:in `block in save!' 42: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/validations.rb:53:in `save!' 41: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/persistence.rb:507:in `save!' 40: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/timestamp.rb:126:in `create_or_update' 39: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/callbacks.rb:457:in `create_or_update' 38: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activesupport-6.1.0/lib/active_support/callbacks.rb:824:in `_run_save_callbacks' 37: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activesupport-6.1.0/lib/active_support/callbacks.rb:98:in `run_callbacks' 36: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/callbacks.rb:457:in `block in create_or_update' 35: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/persistence.rb:900:in `create_or_update' 34: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/timestamp.rb:108:in `_create_record' 33: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/callbacks.rb:461:in `_create_record' 32: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activesupport-6.1.0/lib/active_support/callbacks.rb:824:in `_run_create_callbacks' 31: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activesupport-6.1.0/lib/active_support/callbacks.rb:98:in `run_callbacks' 30: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/callbacks.rb:461:in `block in _create_record' 29: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/attribute_methods/dirty.rb:201:in `_create_record' 28: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/locking/optimistic.rb:79:in `_create_record' 27: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/counter_cache.rb:166:in `_create_record' 26: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/persistence.rb:929:in `_create_record' 25: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/persistence.rb:375:in `_insert_record' 24: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/connection_adapters/abstract/query_cache.rb:22:in `insert' 23: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/connection_adapters/abstract/database_statements.rb:171:in `insert' 22: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/connection_adapters/abstract/database_statements.rb:136:in `exec_insert' 21: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/connection_adapters/mysql/database_statements.rb:55:in `exec_query' 20: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/connection_adapters/abstract_mysql_adapter.rb:215:in `execute_and_free' 19: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/connection_adapters/mysql/database_statements.rb:50:in `execute' 18: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/connection_adapters/abstract_mysql_adapter.rb:204:in `execute' 17: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/connection_adapters/abstract_adapter.rb:688:in `log' 16: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activesupport-6.1.0/lib/active_support/notifications/instrumenter.rb:24:in `instrument' 15: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/connection_adapters/abstract_adapter.rb:696:in `block in log' 14: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activesupport-6.1.0/lib/active_support/concurrency/load_interlock_aware_monitor.rb:21:in `synchronize' 13: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activesupport-6.1.0/lib/active_support/concurrency/load_interlock_aware_monitor.rb:21:in `handle_interrupt' 12: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activesupport-6.1.0/lib/active_support/concurrency/load_interlock_aware_monitor.rb:25:in `block in synchronize' 11: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activesupport-6.1.0/lib/active_support/concurrency/load_interlock_aware_monitor.rb:25:in `handle_interrupt' 10: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activesupport-6.1.0/lib/active_support/concurrency/load_interlock_aware_monitor.rb:26:in `block (2 levels) in synchronize' 9: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/connection_adapters/abstract_adapter.rb:697:in `block (2 levels) in log' 8: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/connection_adapters/abstract_mysql_adapter.rb:205:in `block in execute' 7: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activesupport-6.1.0/lib/active_support/dependencies/interlock.rb:47:in `permit_concurrent_loads' 6: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activesupport-6.1.0/lib/active_support/concurrency/share_lock.rb:187:in `yield_shares' 5: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activesupport-6.1.0/lib/active_support/dependencies/interlock.rb:48:in `block in permit_concurrent_loads' 4: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/connection_adapters/abstract_mysql_adapter.rb:206:in `block (2 levels) in execute' 3: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/mysql2-0.5.3/lib/mysql2/client.rb:130:in `query' 2: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/mysql2-0.5.3/lib/mysql2/client.rb:130:in `handle_interrupt' 1: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/mysql2-0.5.3/lib/mysql2/client.rb:131:in `block in query' /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/mysql2-0.5.3/lib/mysql2/client.rb:131:in `_query': Duplicate entry 'foo' for key 'users.index_users_on_name' (Mysql2::Error) 87: from foo.rb:34:in `<main>' 86: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/transactions.rb:209:in `transaction' 85: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/connection_adapters/abstract/database_statements.rb:320:in `transaction' 84: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/connection_adapters/abstract/transaction.rb:308:in `within_new_transaction' 83: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activesupport-6.1.0/lib/active_support/concurrency/load_interlock_aware_monitor.rb:21:in `synchronize' 82: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activesupport-6.1.0/lib/active_support/concurrency/load_interlock_aware_monitor.rb:21:in `handle_interrupt' 81: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activesupport-6.1.0/lib/active_support/concurrency/load_interlock_aware_monitor.rb:25:in `block in synchronize' 80: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activesupport-6.1.0/lib/active_support/concurrency/load_interlock_aware_monitor.rb:25:in `handle_interrupt' 79: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activesupport-6.1.0/lib/active_support/concurrency/load_interlock_aware_monitor.rb:26:in `block (2 levels) in synchronize' 78: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/connection_adapters/abstract/transaction.rb:310:in `block in within_new_transaction' 77: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/connection_adapters/abstract/database_statements.rb:320:in `block in transaction' 76: from foo.rb:35:in `block in <main>' 75: from foo.rb:41:in `rescue in block in <main>' 74: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/querying.rb:22:in `create_or_find_by!' 73: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/relation.rb:218:in `create_or_find_by!' 72: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/relation/delegation.rb:108:in `method_missing' 71: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/relation.rb:406:in `scoping' 70: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/relation.rb:811:in `_scoping' 69: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/relation.rb:406:in `block in scoping' 68: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/relation/delegation.rb:108:in `block in method_missing' 67: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/relation/delegation.rb:108:in `public_send' 66: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/transactions.rb:209:in `transaction' 65: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/connection_adapters/abstract/database_statements.rb:320:in `transaction' 64: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/connection_adapters/abstract/transaction.rb:308:in `within_new_transaction' 63: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activesupport-6.1.0/lib/active_support/concurrency/load_interlock_aware_monitor.rb:21:in `synchronize' 62: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activesupport-6.1.0/lib/active_support/concurrency/load_interlock_aware_monitor.rb:21:in `handle_interrupt' 61: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activesupport-6.1.0/lib/active_support/concurrency/load_interlock_aware_monitor.rb:25:in `block in synchronize' 60: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activesupport-6.1.0/lib/active_support/concurrency/load_interlock_aware_monitor.rb:25:in `handle_interrupt' 59: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activesupport-6.1.0/lib/active_support/concurrency/load_interlock_aware_monitor.rb:26:in `block (2 levels) in synchronize' 58: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/connection_adapters/abstract/transaction.rb:310:in `block in within_new_transaction' 57: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/connection_adapters/abstract/database_statements.rb:320:in `block in transaction' 56: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/relation.rb:218:in `block in create_or_find_by!' 55: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/relation.rb:114:in `create!' 54: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/relation.rb:406:in `scoping' 53: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/relation.rb:811:in `_scoping' 52: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/relation.rb:406:in `block in scoping' 51: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/relation.rb:114:in `block in create!' 50: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/relation.rb:806:in `_create!' 49: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/persistence.rb:55:in `create!' 48: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/suppressor.rb:48:in `save!' 47: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/transactions.rb:300:in `save!' 46: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/transactions.rb:348:in `with_transaction_returning_status' 45: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/connection_adapters/abstract/database_statements.rb:318:in `transaction' 44: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/transactions.rb:352:in `block in with_transaction_returning_status' 43: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/transactions.rb:300:in `block in save!' 42: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/validations.rb:53:in `save!' 41: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/persistence.rb:507:in `save!' 40: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/timestamp.rb:126:in `create_or_update' 39: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/callbacks.rb:457:in `create_or_update' 38: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activesupport-6.1.0/lib/active_support/callbacks.rb:824:in `_run_save_callbacks' 37: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activesupport-6.1.0/lib/active_support/callbacks.rb:98:in `run_callbacks' 36: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/callbacks.rb:457:in `block in create_or_update' 35: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/persistence.rb:900:in `create_or_update' 34: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/timestamp.rb:108:in `_create_record' 33: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/callbacks.rb:461:in `_create_record' 32: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activesupport-6.1.0/lib/active_support/callbacks.rb:824:in `_run_create_callbacks' 31: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activesupport-6.1.0/lib/active_support/callbacks.rb:98:in `run_callbacks' 30: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/callbacks.rb:461:in `block in _create_record' 29: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/attribute_methods/dirty.rb:201:in `_create_record' 28: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/locking/optimistic.rb:79:in `_create_record' 27: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/counter_cache.rb:166:in `_create_record' 26: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/persistence.rb:929:in `_create_record' 25: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/persistence.rb:375:in `_insert_record' 24: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/connection_adapters/abstract/query_cache.rb:22:in `insert' 23: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/connection_adapters/abstract/database_statements.rb:171:in `insert' 22: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/connection_adapters/abstract/database_statements.rb:136:in `exec_insert' 21: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/connection_adapters/mysql/database_statements.rb:55:in `exec_query' 20: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/connection_adapters/abstract_mysql_adapter.rb:215:in `execute_and_free' 19: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/connection_adapters/mysql/database_statements.rb:50:in `execute' 18: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/connection_adapters/abstract_mysql_adapter.rb:204:in `execute' 17: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/connection_adapters/abstract_adapter.rb:688:in `log' 16: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activesupport-6.1.0/lib/active_support/notifications/instrumenter.rb:24:in `instrument' 15: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/connection_adapters/abstract_adapter.rb:696:in `block in log' 14: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activesupport-6.1.0/lib/active_support/concurrency/load_interlock_aware_monitor.rb:21:in `synchronize' 13: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activesupport-6.1.0/lib/active_support/concurrency/load_interlock_aware_monitor.rb:21:in `handle_interrupt' 12: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activesupport-6.1.0/lib/active_support/concurrency/load_interlock_aware_monitor.rb:25:in `block in synchronize' 11: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activesupport-6.1.0/lib/active_support/concurrency/load_interlock_aware_monitor.rb:25:in `handle_interrupt' 10: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activesupport-6.1.0/lib/active_support/concurrency/load_interlock_aware_monitor.rb:26:in `block (2 levels) in synchronize' 9: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/connection_adapters/abstract_adapter.rb:697:in `block (2 levels) in log' 8: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/connection_adapters/abstract_mysql_adapter.rb:205:in `block in execute' 7: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activesupport-6.1.0/lib/active_support/dependencies/interlock.rb:47:in `permit_concurrent_loads' 6: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activesupport-6.1.0/lib/active_support/concurrency/share_lock.rb:187:in `yield_shares' 5: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activesupport-6.1.0/lib/active_support/dependencies/interlock.rb:48:in `block in permit_concurrent_loads' 4: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/connection_adapters/abstract_mysql_adapter.rb:206:in `block (2 levels) in execute' 3: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/mysql2-0.5.3/lib/mysql2/client.rb:130:in `query' 2: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/mysql2-0.5.3/lib/mysql2/client.rb:130:in `handle_interrupt' 1: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/mysql2-0.5.3/lib/mysql2/client.rb:131:in `block in query' /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/mysql2-0.5.3/lib/mysql2/client.rb:131:in `_query': Mysql2::Error: Duplicate entry 'foo' for key 'users.index_users_on_name' (ActiveRecord::RecordNotUnique) 18: from foo.rb:34:in `<main>' 17: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/transactions.rb:209:in `transaction' 16: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/connection_adapters/abstract/database_statements.rb:320:in `transaction' 15: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/connection_adapters/abstract/transaction.rb:308:in `within_new_transaction' 14: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activesupport-6.1.0/lib/active_support/concurrency/load_interlock_aware_monitor.rb:21:in `synchronize' 13: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activesupport-6.1.0/lib/active_support/concurrency/load_interlock_aware_monitor.rb:21:in `handle_interrupt' 12: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activesupport-6.1.0/lib/active_support/concurrency/load_interlock_aware_monitor.rb:25:in `block in synchronize' 11: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activesupport-6.1.0/lib/active_support/concurrency/load_interlock_aware_monitor.rb:25:in `handle_interrupt' 10: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activesupport-6.1.0/lib/active_support/concurrency/load_interlock_aware_monitor.rb:26:in `block (2 levels) in synchronize' 9: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/connection_adapters/abstract/transaction.rb:310:in `block in within_new_transaction' 8: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/connection_adapters/abstract/database_statements.rb:320:in `block in transaction' 7: from foo.rb:35:in `block in <main>' 6: from foo.rb:41:in `rescue in block in <main>' 5: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/querying.rb:22:in `create_or_find_by!' 4: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/relation.rb:217:in `create_or_find_by!' 3: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/relation.rb:220:in `rescue in create_or_find_by!' 2: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/relation/finder_methods.rb:87:in `find_by!' 1: from /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/relation/finder_methods.rb:104:in `take!' /Users/kamipo/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.1.0/lib/active_record/relation/finder_methods.rb:354:in `raise_record_not_found_exception!': Couldn't find User with [WHERE `users`.`name` = ?] (ActiveRecord::RecordNotFound)
https://gist.github.com/kamipo/480f9e6fb61bef0f36b1edbccfd30f66