Skip to content

Commit dd88c7e

Browse files
authored
Merge pull request rails#51965 from rails/fxn/trx-sql.active_record
Include the current transaction in sql.active_record event payloads
2 parents bc56661 + c16d552 commit dd88c7e

File tree

5 files changed

+75
-0
lines changed

5 files changed

+75
-0
lines changed

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +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,
280281
cached: true
281282
}
282283
end

activerecord/lib/active_record/connection_adapters/abstract_adapter.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1118,6 +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,
11211122
row_count: 0,
11221123
&block
11231124
)

activerecord/test/cases/instrumentation_test.rb

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,5 +170,36 @@ def test_payload_connection_with_query_cache_enabled
170170
ensure
171171
ActiveSupport::Notifications.unsubscribe(subscriber) if subscriber
172172
end
173+
174+
def test_payload_with_implicit_transaction
175+
expected_transaction = Book.current_transaction
176+
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
182+
183+
Book.count
184+
ensure
185+
ActiveSupport::Notifications.unsubscribe(subscriber)
186+
end
187+
188+
def test_payload_with_explicit_transaction
189+
expected_transaction = nil
190+
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
196+
197+
Book.transaction do |transaction|
198+
expected_transaction = transaction
199+
Book.first
200+
end
201+
ensure
202+
ActiveSupport::Notifications.unsubscribe(subscriber)
203+
end
173204
end
174205
end

activerecord/test/cases/query_cache_test.rb

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1067,4 +1067,40 @@ def test_query_cache_lru_eviction
10671067

10681068
assert_equal @connection_1, @connection_2
10691069
end
1070+
1071+
test "payload with implicit transaction" do
1072+
expected_transaction = Task.current_transaction
1073+
1074+
subscriber = ActiveSupport::Notifications.subscribe("sql.active_record") do |event|
1075+
if event.payload[:cached]
1076+
assert_same expected_transaction, event.payload[:transaction]
1077+
end
1078+
end
1079+
1080+
Task.cache do
1081+
2.times { Task.count }
1082+
end
1083+
ensure
1084+
ActiveSupport::Notifications.unsubscribe(subscriber)
1085+
end
1086+
1087+
test "payload with explicit transaction" do
1088+
expected_transaction = nil
1089+
1090+
subscriber = ActiveSupport::Notifications.subscribe("sql.active_record") do |event|
1091+
if event.payload[:cached]
1092+
assert_same expected_transaction, event.payload[:transaction]
1093+
end
1094+
end
1095+
1096+
Task.transaction do |transaction|
1097+
expected_transaction = transaction
1098+
1099+
Task.cache do
1100+
2.times { Task.count }
1101+
end
1102+
end
1103+
ensure
1104+
ActiveSupport::Notifications.unsubscribe(subscriber)
1105+
end
10701106
end

guides/source/active_support_instrumentation.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -360,6 +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 |
363364
| `:binds` | Bind parameters |
364365
| `:type_casted_binds` | Typecasted bind parameters |
365366
| `:statement_name` | SQL Statement name |
@@ -374,13 +375,18 @@ Adapters may add their own data as well.
374375
sql: "SELECT \"posts\".* FROM \"posts\" ",
375376
name: "Post Load",
376377
connection: <ActiveRecord::ConnectionAdapters::SQLite3Adapter:0x00007f9f7a838850>,
378+
transaction: <ActiveRecord::ConnectionAdapters::RealTransaction:0x0000000121b5d3e0>
377379
binds: [<ActiveModel::Attribute::WithCastValue:0x00007fe19d15dc00>],
378380
type_casted_binds: [11],
379381
statement_name: nil,
380382
row_count: 5
381383
}
382384
```
383385

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.
389+
384390
#### `strict_loading_violation.active_record`
385391

386392
This event is only emitted when [`config.active_record.action_on_strict_loading_violation`][] is set to `:log`.

0 commit comments

Comments
 (0)