@@ -5,7 +5,6 @@ module Clients
55
66 # Encapsulates behavior for using sessions and transactions.
77 module Sessions
8-
98 def self . included ( base )
109 base . include ( ClassMethods )
1110 end
@@ -46,8 +45,7 @@ def with_session(options = {})
4645 end
4746 rescue Mongo ::Error ::OperationFailure => ex
4847 if ( ex . code == 40415 && ex . server_message =~ /startTransaction/ ) ||
49- ( ex . code == 20 && ex . server_message =~ /Transaction/ )
50- then
48+ ( ex . code == 20 && ex . server_message =~ /Transaction/ )
5149 raise Mongoid ::Errors ::TransactionsNotSupported . new
5250 else
5351 raise ex
@@ -82,27 +80,66 @@ def transaction(options = {}, session_options: {})
8280 begin
8381 session . start_transaction ( options )
8482 yield
85- session . commit_transaction
83+ commit_transaction ( session )
8684 rescue Mongoid ::Errors ::Rollback
87- session . abort_transaction
85+ abort_transaction ( session )
8886 rescue Mongoid ::Errors ::InvalidSessionNesting
8987 # Session should be ended here.
9088 raise Mongoid ::Errors ::InvalidTransactionNesting . new
9189 rescue Mongo ::Error ::InvalidSession , Mongo ::Error ::InvalidTransactionOperation => e
92- session . abort_transaction
90+ abort_transaction ( session )
9391 raise Mongoid ::Errors ::TransactionError ( e )
9492 rescue StandardError => e
95- session . abort_transaction
93+ abort_transaction ( session )
9694 raise e
9795 end
9896 end
9997 end
10098
10199 private
102100
101+ # @return [ Mongo::Session ] Session for the current client.
103102 def _session
104103 Threaded . get_session ( client : persistence_context . client )
105104 end
105+
106+ # This method should be used to detect whether a persistence operation
107+ # is executed inside transaction or not.
108+ #
109+ # Currently this method is used to detect when +after_commit+ callbacks
110+ # should be triggered. If we introduce implicit transactions and
111+ # therefore do not need to handle two different ways of triggering callbacks,
112+ # we may want to remove this method.
113+ #
114+ # @return [ true | false ] Whether there is a session for the current
115+ # client, and there is a transaction in progress for this session.
116+ def in_transaction?
117+ _session &.in_transaction? || false
118+ end
119+
120+ # Commits the active transaction on the session, and calls
121+ # after_commit callbacks on modified documents.
122+ #
123+ # @param [ Mongo::Session ] session Session on which
124+ # a transaction is started.
125+ def commit_transaction ( session )
126+ session . commit_transaction
127+ Threaded . clear_modified_documents ( session ) . each do |doc |
128+ doc . run_after_callbacks ( :commit )
129+ end
130+ end
131+
132+ # Aborts the active transaction on the session, and calls
133+ # after_rollback callbacks on modified documents.
134+ #
135+ # @param [ Mongo::Session ] session Session on which
136+ # a transaction is started.
137+ def abort_transaction ( session )
138+ session . abort_transaction
139+ Threaded . clear_modified_documents ( session ) . each do |doc |
140+ doc . run_after_callbacks ( :rollback )
141+ end
142+ end
106143 end
107144 end
108145 end
0 commit comments