Skip to content

Commit 23df2aa

Browse files
committed
Lazily generate a UUID for AR transactions
1 parent 1e026db commit 23df2aa

File tree

3 files changed

+34
-0
lines changed

3 files changed

+34
-0
lines changed

activerecord/lib/active_record/connection_adapters/abstract/transaction.rb

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
# frozen_string_literal: true
22

3+
require "active_support/core_ext/digest"
4+
35
module ActiveRecord
46
module ConnectionAdapters
57
# = Active Record Connection Adapters Transaction State
@@ -119,6 +121,7 @@ def materialized?; false; end
119121
def before_commit; yield; end
120122
def after_commit; yield; end
121123
def after_rollback; end # noop
124+
def uuid; Digest::UUID.nil_uuid; end
122125
end
123126

124127
class Transaction < ActiveRecord::Transaction # :nodoc:

activerecord/lib/active_record/transaction.rb

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
# frozen_string_literal: true
22

3+
require "active_support/core_ext/digest"
4+
35
module ActiveRecord
46
class Transaction
57
class Callback # :nodoc:
@@ -23,6 +25,7 @@ def after_rollback
2325

2426
def initialize # :nodoc:
2527
@callbacks = nil
28+
@uuid = nil
2629
end
2730

2831
# Registers a block to be called before the current transaction is fully committed.
@@ -60,6 +63,11 @@ def after_rollback(&block)
6063
(@callbacks ||= []) << Callback.new(:after_rollback, block)
6164
end
6265

66+
# Returns a UUID for this transaction.
67+
def uuid
68+
@uuid ||= Digest::UUID.uuid_v4
69+
end
70+
6371
protected
6472
def append_callbacks(callbacks)
6573
(@callbacks ||= []).concat(callbacks)

activerecord/test/cases/transactions_test.rb

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1650,6 +1650,29 @@ def test_no_automatic_savepoint_for_inner_transaction
16501650
end
16511651
end if Topic.lease_connection.supports_savepoints?
16521652

1653+
class TransactionUUIDTest < ActiveRecord::TestCase
1654+
def test_the_uuid_is_lazily_computed
1655+
Topic.transaction do
1656+
transaction = Topic.connection.current_transaction
1657+
assert_nil transaction.instance_variable_get(:@uuid)
1658+
end
1659+
end
1660+
1661+
def test_the_uuid_for_regular_transactions_is_generated_and_memoized
1662+
Topic.transaction do
1663+
transaction = Topic.connection.current_transaction
1664+
uuid = transaction.uuid
1665+
assert_match(/\A[[:xdigit:]]{8}-(?:[[:xdigit:]]{4}-){3}[[:xdigit:]]{12}\z/, uuid)
1666+
assert_equal uuid, transaction.uuid
1667+
end
1668+
end
1669+
1670+
def test_the_uuid_for_null_transactions_is_the_nil_uuid
1671+
null_transaction = ActiveRecord::ConnectionAdapters::TransactionManager::NULL_TRANSACTION
1672+
assert_equal Digest::UUID.nil_uuid, null_transaction.uuid
1673+
end
1674+
end
1675+
16531676
class ConcurrentTransactionTest < ActiveRecord::TestCase
16541677
if ActiveRecord::Base.lease_connection.supports_transaction_isolation? && !current_adapter?(:SQLite3Adapter)
16551678
self.use_transactional_tests = false

0 commit comments

Comments
 (0)