Skip to content

Commit 4a4ed0f

Browse files
committed
Pass transaction: nil in sql.active_record events if no transaction is open
1 parent 0f3dbe2 commit 4a4ed0f

File tree

5 files changed

+54
-33
lines changed

5 files changed

+54
-33
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -277,7 +277,7 @@ def cache_notification_info(sql, name, binds)
277277
type_casted_binds: -> { type_casted_binds(binds) },
278278
name: name,
279279
connection: self,
280-
transaction: current_transaction,
280+
transaction: current_transaction.presence,
281281
cached: true
282282
}
283283
end

activerecord/lib/active_record/connection_adapters/abstract_adapter.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1118,7 +1118,7 @@ def log(sql, name = "SQL", binds = [], type_casted_binds = [], statement_name =
11181118
statement_name: statement_name,
11191119
async: async,
11201120
connection: self,
1121-
transaction: current_transaction,
1121+
transaction: current_transaction.presence,
11221122
row_count: 0,
11231123
&block
11241124
)

activerecord/test/cases/instrumentation_test.rb

Lines changed: 34 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -170,36 +170,48 @@ def test_payload_connection_with_query_cache_enabled
170170
ensure
171171
ActiveSupport::Notifications.unsubscribe(subscriber) if subscriber
172172
end
173+
end
174+
end
173175

174-
def test_payload_with_implicit_transaction
175-
expected_transaction = Book.current_transaction
176+
class ActiveRecord::TransactionInSqlActiveRecordPayloadTest < ActiveRecord::TestCase
177+
# We need current_transaction to return the null transaction.
178+
self.use_transactional_tests = false
176179

177-
subscriber = ActiveSupport::Notifications.subscribe("sql.active_record") do |event|
178-
if event.payload[:name] == "Book Count"
179-
assert_same expected_transaction, event.payload[:transaction]
180-
end
181-
end
180+
def test_payload_without_an_open_transaction
181+
asserted = false
182182

183-
Book.count
184-
ensure
185-
ActiveSupport::Notifications.unsubscribe(subscriber)
183+
subscriber = ActiveSupport::Notifications.subscribe("sql.active_record") do |event|
184+
if event.payload.fetch(:name) == "Book Count"
185+
assert_nil event.payload.fetch(:transaction)
186+
asserted = true
187+
end
186188
end
187189

188-
def test_payload_with_explicit_transaction
189-
expected_transaction = nil
190+
Book.count
190191

191-
subscriber = ActiveSupport::Notifications.subscribe("sql.active_record") do |event|
192-
if event.payload[:name] == "Book Load"
193-
assert_same expected_transaction, event.payload[:transaction]
194-
end
195-
end
192+
assert asserted
193+
ensure
194+
ActiveSupport::Notifications.unsubscribe(subscriber)
195+
end
196196

197-
Book.transaction do |transaction|
198-
expected_transaction = transaction
199-
Book.first
197+
def test_payload_with_an_open_transaction
198+
asserted = false
199+
expected_transaction = nil
200+
201+
subscriber = ActiveSupport::Notifications.subscribe("sql.active_record") do |event|
202+
if event.payload.fetch(:name) == "Book Count"
203+
assert_same expected_transaction, event.payload.fetch(:transaction)
204+
asserted = true
200205
end
201-
ensure
202-
ActiveSupport::Notifications.unsubscribe(subscriber)
203206
end
207+
208+
Book.transaction do |transaction|
209+
expected_transaction = transaction
210+
Book.count
211+
end
212+
213+
assert asserted
214+
ensure
215+
ActiveSupport::Notifications.unsubscribe(subscriber)
204216
end
205217
end

activerecord/test/cases/query_cache_test.rb

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1067,29 +1067,38 @@ def test_query_cache_lru_eviction
10671067

10681068
assert_equal @connection_1, @connection_2
10691069
end
1070+
end
1071+
1072+
class TransactionInCachedSqlActiveRecordPayloadTest < ActiveRecord::TestCase
1073+
# We need current_transaction to return the null transaction.
1074+
self.use_transactional_tests = false
10701075

1071-
test "payload with implicit transaction" do
1072-
expected_transaction = Task.current_transaction
1076+
def test_payload_without_open_transaction
1077+
asserted = false
10731078

10741079
subscriber = ActiveSupport::Notifications.subscribe("sql.active_record") do |event|
10751080
if event.payload[:cached]
1076-
assert_same expected_transaction, event.payload[:transaction]
1081+
assert_nil event.payload.fetch(:transaction)
1082+
asserted = true
10771083
end
10781084
end
1079-
10801085
Task.cache do
10811086
2.times { Task.count }
10821087
end
1088+
1089+
assert asserted
10831090
ensure
10841091
ActiveSupport::Notifications.unsubscribe(subscriber)
10851092
end
10861093

1087-
test "payload with explicit transaction" do
1094+
def test_payload_with_open_transaction
1095+
asserted = false
10881096
expected_transaction = nil
10891097

10901098
subscriber = ActiveSupport::Notifications.subscribe("sql.active_record") do |event|
10911099
if event.payload[:cached]
10921100
assert_same expected_transaction, event.payload[:transaction]
1101+
asserted = true
10931102
end
10941103
end
10951104

@@ -1100,6 +1109,8 @@ def test_query_cache_lru_eviction
11001109
2.times { Task.count }
11011110
end
11021111
end
1112+
1113+
assert asserted
11031114
ensure
11041115
ActiveSupport::Notifications.unsubscribe(subscriber)
11051116
end

guides/source/active_support_instrumentation.md

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -360,7 +360,7 @@ The `:cache_hits` key is only included if the collection is rendered with `cache
360360
| `:sql` | SQL statement |
361361
| `:name` | Name of the operation |
362362
| `:connection` | Connection object |
363-
| `:transaction` | Current transaction |
363+
| `:transaction` | Current transaction, if any |
364364
| `:binds` | Bind parameters |
365365
| `:type_casted_binds` | Typecasted bind parameters |
366366
| `:statement_name` | SQL Statement name |
@@ -383,9 +383,7 @@ Adapters may add their own data as well.
383383
}
384384
```
385385

386-
If there is no transaction started at the moment, `:transaction` has a null
387-
object with UUID `00000000-0000-0000-0000-000000000000` (the nil UUID). This may
388-
happen, for example, issuing a `SELECT` not wrapped in a transaction.
386+
If the query is not executed in the context of a transaction, `:transaction` is `nil`.
389387

390388
#### `strict_loading_violation.active_record`
391389

0 commit comments

Comments
 (0)