Skip to content

New find_or_create_by behaviour raises RecordNotFound in edge rails #48035

@jdelStrother

Description

@jdelStrother

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)

cc @casperisfine

System configuration

Rails version: 7.1.0 alpha @ 719558c

Ruby version: 3.1.3

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions