@@ -28,9 +28,9 @@ var ErrWrongClient = errors.New("session was not created by this client")
28
28
29
29
var withTransactionTimeout = 120 * time .Second
30
30
31
- // SessionContext is a hybrid interface. It combines a context. Context with
32
- // a mongo.Session. This type can be used as a regular context.Context or
33
- // Session type. It is not goroutine safe and should not be used in multiple goroutines concurrently .
31
+ // SessionContext combines the context.Context and mongo.Session interfaces. It should be used as the Context arguments
32
+ // to operations that should be executed in a session. This type is not goroutine safe and must not be used concurrently
33
+ // by multiple goroutines.
34
34
type SessionContext interface {
35
35
context.Context
36
36
Session
@@ -44,20 +44,51 @@ type sessionContext struct {
44
44
type sessionKey struct {
45
45
}
46
46
47
- // Session is the interface that represents a sequential set of operations executed.
48
- // Instances of this interface can be used to use transactions against the server
49
- // and to enable causally consistent behavior for applications.
47
+ // Session is an interface that represents a MongoDB logical session. Sessions can be used to enable causal consistency
48
+ // for a group of operations or to execute operations in an ACID transaction. A new Session can be created from a Client
49
+ // instance. A Session created from a Client must only be used to execute operations using that Client or a Database or
50
+ // Collection created from that Client. Custom implementations of this interface should not be used in production. For
51
+ // more information about sessions, and their use cases, see https://docs.mongodb.com/manual/reference/server-sessions/,
52
+ // https://docs.mongodb.com/manual/core/read-isolation-consistency-recency/#causal-consistency, and
53
+ // https://docs.mongodb.com/manual/core/transactions/.
54
+ //
55
+ // StartTransaction starts a new transaction, configured with the given options, on this session. This method will
56
+ // return an error if there is already a transaction in-progress for this session.
57
+ //
58
+ // CommitTransaction commits the active transaction for this session. This method will return an error if there is no
59
+ // active transaction for this session or the transaction has been aborted.
60
+ //
61
+ // AbortTransaction aborts the active transaction for this session. This method will return an error if there is no
62
+ // active transaction for this session or the transaction has been committed or aborted.
63
+ //
64
+ // WithTransaction starts a transaction on this session and runs the fn callback. Errors with the
65
+ // TransientTransactionError and UnknownTransactionCommitResult labels are retried for up to 120 seconds. Inside the
66
+ // callback, sessCtx must be used as the Context parameter for any operations that should be part of the transaction. If
67
+ // the ctx parameter already has a Session attached to it, it will be replaced by this session. The fn callback may be
68
+ // run multiple times during WithTransaction due to retry attempts, so it must be idempotent. Non-retryable operation
69
+ // errors or any operation errors that occur after the timeout expires will be returned without retrying. For a usage
70
+ // example, see the Client.StartSession method documentation.
71
+ //
72
+ // ClusterTime, OperationTime, and Client return the session's current operation time, the session's current cluster
73
+ // time, and the Client associated with the session, respectively.
74
+ //
75
+ // EndSession method should abort any existing transactions and close the session.
76
+ //
77
+ // AdvanceClusterTime and AdvanceOperationTime are for internal use only and must not be called.
50
78
type Session interface {
51
- EndSession (context.Context )
52
- WithTransaction (ctx context.Context , fn func (sessCtx SessionContext ) (interface {}, error ), opts ... * options.TransactionOptions ) (interface {}, error )
53
79
StartTransaction (... * options.TransactionOptions ) error
54
80
AbortTransaction (context.Context ) error
55
81
CommitTransaction (context.Context ) error
82
+ WithTransaction (ctx context.Context , fn func (sessCtx SessionContext ) (interface {}, error ),
83
+ opts ... * options.TransactionOptions ) (interface {}, error )
56
84
ClusterTime () bson.Raw
57
- AdvanceClusterTime (bson.Raw ) error
58
85
OperationTime () * primitive.Timestamp
59
- AdvanceOperationTime (* primitive.Timestamp ) error
60
86
Client () * Client
87
+ EndSession (context.Context )
88
+
89
+ AdvanceClusterTime (bson.Raw ) error
90
+ AdvanceOperationTime (* primitive.Timestamp ) error
91
+
61
92
session ()
62
93
}
63
94
@@ -89,7 +120,7 @@ func (s *sessionImpl) ID() bsonx.Doc {
89
120
return s .clientSession .SessionID
90
121
}
91
122
92
- // EndSession ends the session .
123
+ // EndSession implements the Session interface .
93
124
func (s * sessionImpl ) EndSession (ctx context.Context ) {
94
125
if s .clientSession .TransactionInProgress () {
95
126
// ignore all errors aborting during an end session
@@ -98,18 +129,9 @@ func (s *sessionImpl) EndSession(ctx context.Context) {
98
129
s .clientSession .EndSession ()
99
130
}
100
131
101
- // WithTransaction creates a transaction on this session and runs the given callback, retrying for
102
- // TransientTransactionError and UnknownTransactionCommitResult errors. The only way to provide a
103
- // session to a CRUD method is to invoke that CRUD method with the mongo.SessionContext within the
104
- // callback. The mongo.SessionContext can be used as a regular context, so methods like
105
- // context.WithDeadline and context.WithTimeout are supported.
106
- //
107
- // If the context.Context already has a mongo.Session attached, that mongo.Session will be replaced
108
- // with the one provided.
109
- //
110
- // The callback may be run multiple times due to retry attempts. Non-retryable and timed out errors
111
- // are returned from this function.
112
- func (s * sessionImpl ) WithTransaction (ctx context.Context , fn func (sessCtx SessionContext ) (interface {}, error ), opts ... * options.TransactionOptions ) (interface {}, error ) {
132
+ // WithTransaction implements the Session interface.
133
+ func (s * sessionImpl ) WithTransaction (ctx context.Context , fn func (sessCtx SessionContext ) (interface {}, error ),
134
+ opts ... * options.TransactionOptions ) (interface {}, error ) {
113
135
timeout := time .NewTimer (withTransactionTimeout )
114
136
defer timeout .Stop ()
115
137
var err error
@@ -170,7 +192,7 @@ func (s *sessionImpl) WithTransaction(ctx context.Context, fn func(sessCtx Sessi
170
192
}
171
193
}
172
194
173
- // StartTransaction starts a transaction for this session .
195
+ // StartTransaction implements the Session interface .
174
196
func (s * sessionImpl ) StartTransaction (opts ... * options.TransactionOptions ) error {
175
197
err := s .clientSession .CheckStartTransaction ()
176
198
if err != nil {
@@ -190,7 +212,7 @@ func (s *sessionImpl) StartTransaction(opts ...*options.TransactionOptions) erro
190
212
return s .clientSession .StartTransaction (coreOpts )
191
213
}
192
214
193
- // AbortTransaction aborts the session's transaction, returning any errors and error codes
215
+ // AbortTransaction implements the Session interface.
194
216
func (s * sessionImpl ) AbortTransaction (ctx context.Context ) error {
195
217
err := s .clientSession .CheckAbortTransaction ()
196
218
if err != nil {
@@ -207,15 +229,16 @@ func (s *sessionImpl) AbortTransaction(ctx context.Context) error {
207
229
s .clientSession .Aborting = true
208
230
_ = operation .NewAbortTransaction ().Session (s .clientSession ).ClusterClock (s .client .clock ).Database ("admin" ).
209
231
Deployment (s .deployment ).WriteConcern (s .clientSession .CurrentWc ).ServerSelector (selector ).
210
- Retry (driver .RetryOncePerCommand ).CommandMonitor (s .client .monitor ).RecoveryToken (bsoncore .Document (s .clientSession .RecoveryToken )).Execute (ctx )
232
+ Retry (driver .RetryOncePerCommand ).CommandMonitor (s .client .monitor ).
233
+ RecoveryToken (bsoncore .Document (s .clientSession .RecoveryToken )).Execute (ctx )
211
234
212
235
s .clientSession .Aborting = false
213
236
_ = s .clientSession .AbortTransaction ()
214
237
215
238
return nil
216
239
}
217
240
218
- // CommitTransaction commits the sesson's transaction .
241
+ // CommitTransaction implements the Session interface .
219
242
func (s * sessionImpl ) CommitTransaction (ctx context.Context ) error {
220
243
err := s .clientSession .CheckCommitTransaction ()
221
244
if err != nil {
@@ -256,26 +279,32 @@ func (s *sessionImpl) CommitTransaction(ctx context.Context) error {
256
279
return commitErr
257
280
}
258
281
282
+ // ClusterTime implements the Session interface.
259
283
func (s * sessionImpl ) ClusterTime () bson.Raw {
260
284
return s .clientSession .ClusterTime
261
285
}
262
286
287
+ // AdvanceClusterTime implements the Session interface.
263
288
func (s * sessionImpl ) AdvanceClusterTime (d bson.Raw ) error {
264
289
return s .clientSession .AdvanceClusterTime (d )
265
290
}
266
291
292
+ // OperationTime implements the Session interface.
267
293
func (s * sessionImpl ) OperationTime () * primitive.Timestamp {
268
294
return s .clientSession .OperationTime
269
295
}
270
296
297
+ // AdvanceOperationTime implements the Session interface.
271
298
func (s * sessionImpl ) AdvanceOperationTime (ts * primitive.Timestamp ) error {
272
299
return s .clientSession .AdvanceOperationTime (ts )
273
300
}
274
301
302
+ // Client implements the Session interface.
275
303
func (s * sessionImpl ) Client () * Client {
276
304
return s .client
277
305
}
278
306
307
+ // session implements the Session interface.
279
308
func (* sessionImpl ) session () {
280
309
}
281
310
@@ -290,6 +319,7 @@ func sessionFromContext(ctx context.Context) *session.Client {
290
319
return nil
291
320
}
292
321
322
+ // contextWithSession creates a new SessionContext associated with the given Context and Session parameters.
293
323
func contextWithSession (ctx context.Context , sess Session ) SessionContext {
294
324
return & sessionContext {
295
325
Context : context .WithValue (ctx , sessionKey {}, sess ),
0 commit comments