5
5
module ActiveRecord
6
6
# Class specifies the interface to interact with the current transaction state.
7
7
#
8
- # It can either map to an actual transaction or represent the abscence of a transaction.
8
+ # It can either map to an actual transaction/savepoint, or represent the
9
+ # abscence of a transaction.
9
10
#
10
11
# == State
11
12
#
12
- # You can check whether a transaction is open with the +open?+ or +closed?+ methods
13
+ # We say that a transaction is _finalized_ when it wraps a real transaction
14
+ # that has been either committed or rolled back.
15
+ #
16
+ # A transaction is _open_ if it wraps a real transaction that is not finalized.
17
+ #
18
+ # On the other hand, a transaction is _closed_ when it is not open. That is,
19
+ # when it represents absence of transaction, or it wraps a real but finalized
20
+ # one.
21
+ #
22
+ # You can check whether a transaction is open or closed with the +open?+ and
23
+ # +closed?+ predicates:
13
24
#
14
25
# if Article.current_transaction.open?
15
- # # We are inside a transaction
26
+ # # We are inside a real and not finalized transaction.
16
27
# end
17
28
#
29
+ # Closed transactions are `blank?` too.
30
+ #
18
31
# == Callbacks
19
32
#
20
33
# After updating the database state, you may sometimes need to perform some extra work, or reflect these
@@ -60,16 +73,15 @@ def initialize(internal_transaction) # :nodoc:
60
73
61
74
# Registers a block to be called after the transaction is fully committed.
62
75
#
63
- # If there is no currently open transactions, the block is called immediately.
76
+ # If there is no currently open transactions, the block is called
77
+ # immediately, unless the transaction is finalized, in which case attempting
78
+ # to register the callback raises ActiveRecord::ActiveRecordError.
64
79
#
65
80
# If the transaction has a parent transaction, the callback is transferred to
66
81
# the parent when the current transaction commits, or dropped when the current transaction
67
82
# is rolled back. This operation is repeated until the outermost transaction is reached.
68
83
#
69
84
# If the callback raises an error, the transaction remains committed.
70
- #
71
- # If the transaction is already finalized, attempting to register a callback
72
- # will raise ActiveRecord::ActiveRecordError
73
85
def after_commit ( &block )
74
86
if @internal_transaction . nil?
75
87
yield
@@ -80,7 +92,9 @@ def after_commit(&block)
80
92
81
93
# Registers a block to be called after the transaction is rolled back.
82
94
#
83
- # If there is no currently open transactions, the block is never called.
95
+ # If there is no currently open transactions, the block is not called. But
96
+ # if the transaction is finalized, attempting to register the callback
97
+ # raises ActiveRecord::ActiveRecordError.
84
98
#
85
99
# If the transaction is successfully committed but has a parent
86
100
# transaction, the callback is automatically added to the parent transaction.
@@ -89,17 +103,17 @@ def after_commit(&block)
89
103
# the block is never called.
90
104
#
91
105
# If the transaction is already finalized, attempting to register a callback
92
- # will raise ActiveRecord::ActiveRecordError
106
+ # will raise ActiveRecord::ActiveRecordError.
93
107
def after_rollback ( &block )
94
108
@internal_transaction &.after_rollback ( &block )
95
109
end
96
110
97
- # Returns true if the transaction exists and isn't finalized yet
111
+ # Returns true if the transaction exists and isn't finalized yet.
98
112
def open?
99
113
!closed?
100
114
end
101
115
102
- # Returns true if the transaction doesn't exists or is finalized (committed or rolled back)
116
+ # Returns true if the transaction doesn't exists or is finalized.
103
117
def closed?
104
118
@internal_transaction . nil? || @internal_transaction . state . finalized?
105
119
end
0 commit comments