-
Notifications
You must be signed in to change notification settings - Fork 22k
Closed
Labels
Description
Steps to reproduce
# frozen_string_literal: true
require "bundler/inline"
gemfile(true) do
source "https://rubygems.org"
git_source(:github) { |repo| "https://github.com/#{repo}.git" }
gem "rails", github: "rails/rails", branch: "main"
gem "mysql2"
end
require "active_record"
require "minitest/autorun"
require "logger"
opts = {
database: "unique_keys_test",
adapter: "mysql2",
username: "root"
}
ActiveRecord::Base.logger = Logger.new(STDOUT)
ActiveRecord::Base.establish_connection(opts.except(:database))
ActiveRecord::Base.connection.drop_database(opts[:database])
ActiveRecord::Base.connection.create_database(opts[:database])
ActiveRecord::Base.establish_connection(opts)
ActiveRecord::Schema.define do
create_table :tags, force: true do |t|
t.string :name
t.index :name, unique: true
end
end
class Tag < ActiveRecord::Base
end
class BugTest < Minitest::Test
def test_find_or_create_by
concurrently do
Tag.find_or_create_by(name: "foo")
rescue ActiveRecord::RecordNotUnique
# some app logic that handles RecordNotUnique
end
assert_equal 1, Tag.count
end
def concurrently(&block)
2.times.map {
Thread.new {
Tag.transaction {
block.call
}
}
}.map(&:join)
end
end
Expected behavior
In Rails 7.0, one of the find_or_create_by
calls raises RecordNotUnique (which we rescue and handle at the application-level).
Actual behavior
In 7.1 alpha, it raises RecordNotFound:
Backtrace
/Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activerecord/lib/active_record/relation/finder_methods.rb:380:in `raise_record_not_found_exception!': Couldn't find Tag with [WHERE `tags`.`name` = ?] (ActiveRecord::RecordNotFound)
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activerecord/lib/active_record/relation/finder_methods.rb:104:in `take!'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activerecord/lib/active_record/relation/finder_methods.rb:87:in `find_by!'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activerecord/lib/active_record/relation.rb:218:in `rescue in create_or_find_by'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activerecord/lib/active_record/relation.rb:215:in `create_or_find_by'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activerecord/lib/active_record/relation.rb:176:in `find_or_create_by'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activerecord/lib/active_record/querying.rb:23:in `find_or_create_by'
from uniquekeys.rb:43:in `block in test_association_stuff'
from uniquekeys.rb:54:in `block (3 levels) in concurrently'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activerecord/lib/active_record/connection_adapters/abstract/transaction.rb:490:in `block in within_new_transaction'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activesupport/lib/active_support/concurrency/null_lock.rb:9:in `synchronize'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activerecord/lib/active_record/connection_adapters/abstract/transaction.rb:488:in `within_new_transaction'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb:327:in `transaction'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activerecord/lib/active_record/transactions.rb:212:in `transaction'
from uniquekeys.rb:53:in `block (2 levels) in concurrently'
/Users/jon/Developer/web/vendor/bundle/nix-bundle/ruby/3.1.0/gems/mysql2-0.5.5/lib/mysql2/client.rb:151:in `_query': Mysql2::Error: Duplicate entry 'foo' for key 'tags.index_tags_on_name' (ActiveRecord::RecordNotUnique)
from /Users/jon/Developer/web/vendor/bundle/nix-bundle/ruby/3.1.0/gems/mysql2-0.5.5/lib/mysql2/client.rb:151:in `block in query'
from /Users/jon/Developer/web/vendor/bundle/nix-bundle/ruby/3.1.0/gems/mysql2-0.5.5/lib/mysql2/client.rb:150:in `handle_interrupt'
from /Users/jon/Developer/web/vendor/bundle/nix-bundle/ruby/3.1.0/gems/mysql2-0.5.5/lib/mysql2/client.rb:150:in `query'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb:742:in `block (2 levels) in raw_execute'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb:1011:in `block in with_raw_connection'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activesupport/lib/active_support/concurrency/null_lock.rb:9:in `synchronize'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb:983:in `with_raw_connection'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb:740:in `block in raw_execute'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activesupport/lib/active_support/notifications/instrumenter.rb:58:in `instrument'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb:1121:in `log'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb:739:in `raw_execute'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb:232:in `execute'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb:239:in `execute_and_free'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activerecord/lib/active_record/connection_adapters/mysql/database_statements.rb:47:in `exec_query'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb:142:in `exec_insert'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb:177:in `insert'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb:22:in `insert'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activerecord/lib/active_record/persistence.rb:583:in `_insert_record'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activerecord/lib/active_record/persistence.rb:1238:in `_create_record'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activerecord/lib/active_record/counter_cache.rb:177:in `_create_record'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activerecord/lib/active_record/locking/optimistic.rb:84:in `_create_record'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activerecord/lib/active_record/encryption/encryptable_record.rb:174:in `_create_record'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activerecord/lib/active_record/attribute_methods/dirty.rb:205:in `_create_record'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activerecord/lib/active_record/callbacks.rb:445:in `block in _create_record'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activesupport/lib/active_support/callbacks.rb:99:in `run_callbacks'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activesupport/lib/active_support/callbacks.rb:947:in `_run_create_callbacks'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activerecord/lib/active_record/callbacks.rb:445:in `_create_record'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activerecord/lib/active_record/timestamp.rb:114:in `_create_record'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activerecord/lib/active_record/persistence.rb:1209:in `create_or_update'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activerecord/lib/active_record/callbacks.rb:441:in `block in create_or_update'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activesupport/lib/active_support/callbacks.rb:99:in `run_callbacks'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activesupport/lib/active_support/callbacks.rb:947:in `_run_save_callbacks'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activerecord/lib/active_record/callbacks.rb:441:in `create_or_update'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activerecord/lib/active_record/timestamp.rb:132:in `create_or_update'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activerecord/lib/active_record/persistence.rb:709:in `save'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activerecord/lib/active_record/validations.rb:49:in `save'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activerecord/lib/active_record/transactions.rb:309:in `block in save'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activerecord/lib/active_record/transactions.rb:365:in `block in with_transaction_returning_status'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb:325:in `transaction'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activerecord/lib/active_record/transactions.rb:361:in `with_transaction_returning_status'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activerecord/lib/active_record/transactions.rb:309:in `save'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activerecord/lib/active_record/suppressor.rb:52:in `save'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activerecord/lib/active_record/persistence.rb:38:in `create'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activerecord/lib/active_record/relation.rb:891:in `_create'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activerecord/lib/active_record/relation.rb:103:in `block in create'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activerecord/lib/active_record/relation.rb:906:in `_scoping'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activerecord/lib/active_record/relation.rb:444:in `scoping'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activerecord/lib/active_record/relation.rb:103:in `create'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activerecord/lib/active_record/relation.rb:216:in `block in create_or_find_by'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activerecord/lib/active_record/connection_adapters/abstract/transaction.rb:490:in `block in within_new_transaction'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activesupport/lib/active_support/concurrency/null_lock.rb:9:in `synchronize'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activerecord/lib/active_record/connection_adapters/abstract/transaction.rb:488:in `within_new_transaction'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb:327:in `transaction'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activerecord/lib/active_record/transactions.rb:212:in `transaction'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activerecord/lib/active_record/relation/delegation.rb:79:in `block in transaction'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activerecord/lib/active_record/relation.rb:906:in `_scoping'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activerecord/lib/active_record/relation.rb:444:in `scoping'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activerecord/lib/active_record/relation/delegation.rb:79:in `transaction'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activerecord/lib/active_record/relation.rb:216:in `create_or_find_by'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activerecord/lib/active_record/relation.rb:176:in `find_or_create_by'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activerecord/lib/active_record/querying.rb:23:in `find_or_create_by'
from uniquekeys.rb:43:in `block in test_association_stuff'
from uniquekeys.rb:54:in `block (3 levels) in concurrently'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activerecord/lib/active_record/connection_adapters/abstract/transaction.rb:490:in `block in within_new_transaction'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activesupport/lib/active_support/concurrency/null_lock.rb:9:in `synchronize'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activerecord/lib/active_record/connection_adapters/abstract/transaction.rb:488:in `within_new_transaction'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb:327:in `transaction'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activerecord/lib/active_record/transactions.rb:212:in `transaction'
from uniquekeys.rb:53:in `block (2 levels) in concurrently'
/Users/jon/Developer/web/vendor/bundle/nix-bundle/ruby/3.1.0/gems/mysql2-0.5.5/lib/mysql2/client.rb:151:in `_query': Duplicate entry 'foo' for key 'tags.index_tags_on_name' (Mysql2::Error)
from /Users/jon/Developer/web/vendor/bundle/nix-bundle/ruby/3.1.0/gems/mysql2-0.5.5/lib/mysql2/client.rb:151:in `block in query'
from /Users/jon/Developer/web/vendor/bundle/nix-bundle/ruby/3.1.0/gems/mysql2-0.5.5/lib/mysql2/client.rb:150:in `handle_interrupt'
from /Users/jon/Developer/web/vendor/bundle/nix-bundle/ruby/3.1.0/gems/mysql2-0.5.5/lib/mysql2/client.rb:150:in `query'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb:742:in `block (2 levels) in raw_execute'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb:1011:in `block in with_raw_connection'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activesupport/lib/active_support/concurrency/null_lock.rb:9:in `synchronize'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb:983:in `with_raw_connection'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb:740:in `block in raw_execute'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activesupport/lib/active_support/notifications/instrumenter.rb:58:in `instrument'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb:1121:in `log'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb:739:in `raw_execute'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb:232:in `execute'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb:239:in `execute_and_free'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activerecord/lib/active_record/connection_adapters/mysql/database_statements.rb:47:in `exec_query'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb:142:in `exec_insert'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb:177:in `insert'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb:22:in `insert'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activerecord/lib/active_record/persistence.rb:583:in `_insert_record'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activerecord/lib/active_record/persistence.rb:1238:in `_create_record'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activerecord/lib/active_record/counter_cache.rb:177:in `_create_record'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activerecord/lib/active_record/locking/optimistic.rb:84:in `_create_record'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activerecord/lib/active_record/encryption/encryptable_record.rb:174:in `_create_record'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activerecord/lib/active_record/attribute_methods/dirty.rb:205:in `_create_record'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activerecord/lib/active_record/callbacks.rb:445:in `block in _create_record'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activesupport/lib/active_support/callbacks.rb:99:in `run_callbacks'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activesupport/lib/active_support/callbacks.rb:947:in `_run_create_callbacks'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activerecord/lib/active_record/callbacks.rb:445:in `_create_record'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activerecord/lib/active_record/timestamp.rb:114:in `_create_record'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activerecord/lib/active_record/persistence.rb:1209:in `create_or_update'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activerecord/lib/active_record/callbacks.rb:441:in `block in create_or_update'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activesupport/lib/active_support/callbacks.rb:99:in `run_callbacks'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activesupport/lib/active_support/callbacks.rb:947:in `_run_save_callbacks'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activerecord/lib/active_record/callbacks.rb:441:in `create_or_update'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activerecord/lib/active_record/timestamp.rb:132:in `create_or_update'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activerecord/lib/active_record/persistence.rb:709:in `save'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activerecord/lib/active_record/validations.rb:49:in `save'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activerecord/lib/active_record/transactions.rb:309:in `block in save'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activerecord/lib/active_record/transactions.rb:365:in `block in with_transaction_returning_status'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb:325:in `transaction'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activerecord/lib/active_record/transactions.rb:361:in `with_transaction_returning_status'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activerecord/lib/active_record/transactions.rb:309:in `save'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activerecord/lib/active_record/suppressor.rb:52:in `save'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activerecord/lib/active_record/persistence.rb:38:in `create'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activerecord/lib/active_record/relation.rb:891:in `_create'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activerecord/lib/active_record/relation.rb:103:in `block in create'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activerecord/lib/active_record/relation.rb:906:in `_scoping'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activerecord/lib/active_record/relation.rb:444:in `scoping'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activerecord/lib/active_record/relation.rb:103:in `create'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activerecord/lib/active_record/relation.rb:216:in `block in create_or_find_by'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activerecord/lib/active_record/connection_adapters/abstract/transaction.rb:490:in `block in within_new_transaction'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activesupport/lib/active_support/concurrency/null_lock.rb:9:in `synchronize'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activerecord/lib/active_record/connection_adapters/abstract/transaction.rb:488:in `within_new_transaction'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb:327:in `transaction'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activerecord/lib/active_record/transactions.rb:212:in `transaction'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activerecord/lib/active_record/relation/delegation.rb:79:in `block in transaction'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activerecord/lib/active_record/relation.rb:906:in `_scoping'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activerecord/lib/active_record/relation.rb:444:in `scoping'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activerecord/lib/active_record/relation/delegation.rb:79:in `transaction'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activerecord/lib/active_record/relation.rb:216:in `create_or_find_by'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activerecord/lib/active_record/relation.rb:176:in `find_or_create_by'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activerecord/lib/active_record/querying.rb:23:in `find_or_create_by'
from uniquekeys.rb:43:in `block in test_association_stuff'
from uniquekeys.rb:54:in `block (3 levels) in concurrently'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activerecord/lib/active_record/connection_adapters/abstract/transaction.rb:490:in `block in within_new_transaction'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activesupport/lib/active_support/concurrency/null_lock.rb:9:in `synchronize'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activerecord/lib/active_record/connection_adapters/abstract/transaction.rb:488:in `within_new_transaction'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb:327:in `transaction'
from /Users/jon/Developer/web/vendor/cache/rails-ea7ac1594b4e/activerecord/lib/active_record/transactions.rb:212:in `transaction'
from uniquekeys.rb:53:in `block (2 levels) in concurrently'
though, apparently, only when there's a transaction wrapping the find_or_create call. Without the transaction, the new find_or_create_by improvements successfully return a tag in both threads.
(I'd happily remove our rescue block and leave Rails to handle the unique keys internally, if find_or_create can be fixed to do so)
System configuration
Rails version: 7.1.0 alpha @ 719558c
Ruby version: 3.1.3