Skip to content

Commit 2cb30a7

Browse files
authored
CSHARP-3552: CSOT: Transactions (#1745)
1 parent 6cabd8d commit 2cb30a7

31 files changed

+810
-337
lines changed
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/* Copyright 2010-present MongoDB Inc.
2+
*
3+
* Licensed under the Apache License, Version 2.0 (the "License");
4+
* you may not use this file except in compliance with the License.
5+
* You may obtain a copy of the License at
6+
*
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* Unless required by applicable law or agreed to in writing, software
10+
* distributed under the License is distributed on an "AS IS" BASIS,
11+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
* See the License for the specific language governing permissions and
13+
* limitations under the License.
14+
*/
15+
16+
using System;
17+
using MongoDB.Driver.Core.Misc;
18+
19+
namespace MongoDB.Driver
20+
{
21+
// TODO: CSOT: Make it public when CSOT will be ready for GA
22+
internal sealed class AbortTransactionOptions
23+
{
24+
public AbortTransactionOptions(TimeSpan? timeout)
25+
{
26+
Timeout = Ensure.IsNullOrValidTimeout(timeout, nameof(timeout));
27+
}
28+
29+
public TimeSpan? Timeout { get; }
30+
}
31+
}

src/MongoDB.Driver/ClientSessionHandle.cs

Lines changed: 26 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* Copyright 2017-present MongoDB Inc.
1+
/* Copyright 2010-present MongoDB Inc.
22
*
33
* Licensed under the Apache License, Version 2.0 (the "License");
44
* you may not use this file except in compliance with the License.
@@ -26,7 +26,7 @@ namespace MongoDB.Driver
2626
/// A client session handle.
2727
/// </summary>
2828
/// <seealso cref="MongoDB.Driver.IClientSessionHandle" />
29-
internal sealed class ClientSessionHandle : IClientSessionHandle
29+
internal sealed class ClientSessionHandle : IClientSessionHandle, IClientSessionInternal
3030
{
3131
// private fields
3232
private readonly IMongoClient _client;
@@ -94,16 +94,20 @@ public IServerSession ServerSession
9494

9595
// public methods
9696
/// <inheritdoc />
97-
public void AbortTransaction(CancellationToken cancellationToken = default(CancellationToken))
98-
{
99-
_coreSession.AbortTransaction(cancellationToken);
100-
}
97+
public void AbortTransaction(CancellationToken cancellationToken = default)
98+
=> _coreSession.AbortTransaction(cancellationToken);
99+
100+
// TODO: CSOT: Make it public when CSOT will be ready for GA and add default value to cancellationToken parameter.
101+
void IClientSessionInternal.AbortTransaction(AbortTransactionOptions options, CancellationToken cancellationToken)
102+
=> _coreSession.AbortTransaction(options, cancellationToken);
101103

102104
/// <inheritdoc />
103-
public Task AbortTransactionAsync(CancellationToken cancellationToken = default(CancellationToken))
104-
{
105-
return _coreSession.AbortTransactionAsync(cancellationToken);
106-
}
105+
public Task AbortTransactionAsync(CancellationToken cancellationToken = default)
106+
=> _coreSession.AbortTransactionAsync(cancellationToken);
107+
108+
// TODO: CSOT: Make it public when CSOT will be ready for GA and add default value to cancellationToken parameter.
109+
Task IClientSessionInternal.AbortTransactionAsync(AbortTransactionOptions options, CancellationToken cancellationToken)
110+
=> _coreSession.AbortTransactionAsync(options, cancellationToken);
107111

108112
/// <inheritdoc />
109113
public void AdvanceClusterTime(BsonDocument newClusterTime)
@@ -118,16 +122,20 @@ public void AdvanceOperationTime(BsonTimestamp newOperationTime)
118122
}
119123

120124
/// <inheritdoc />
121-
public void CommitTransaction(CancellationToken cancellationToken = default(CancellationToken))
122-
{
123-
_coreSession.CommitTransaction(cancellationToken);
124-
}
125+
public void CommitTransaction(CancellationToken cancellationToken = default)
126+
=> _coreSession.CommitTransaction(cancellationToken);
127+
128+
// TODO: CSOT: Make it public when CSOT will be ready for GA and add default value to cancellationToken parameter.
129+
void IClientSessionInternal.CommitTransaction(CommitTransactionOptions options, CancellationToken cancellationToken)
130+
=> _coreSession.CommitTransaction(options, cancellationToken);
125131

126132
/// <inheritdoc />
127-
public Task CommitTransactionAsync(CancellationToken cancellationToken = default(CancellationToken))
128-
{
129-
return _coreSession.CommitTransactionAsync(cancellationToken);
130-
}
133+
public Task CommitTransactionAsync(CancellationToken cancellationToken = default)
134+
=> _coreSession.CommitTransactionAsync(cancellationToken);
135+
136+
// TODO: CSOT: Make it public when CSOT will be ready for GA and add default value to cancellationToken parameter.
137+
Task IClientSessionInternal.CommitTransactionAsync(CommitTransactionOptions options, CancellationToken cancellationToken)
138+
=> _coreSession.CommitTransactionAsync(options, cancellationToken);
131139

132140
/// <inheritdoc />
133141
public void Dispose()
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/* Copyright 2010-present MongoDB Inc.
2+
*
3+
* Licensed under the Apache License, Version 2.0 (the "License");
4+
* you may not use this file except in compliance with the License.
5+
* You may obtain a copy of the License at
6+
*
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* Unless required by applicable law or agreed to in writing, software
10+
* distributed under the License is distributed on an "AS IS" BASIS,
11+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
* See the License for the specific language governing permissions and
13+
* limitations under the License.
14+
*/
15+
16+
using System;
17+
using MongoDB.Driver.Core.Misc;
18+
19+
namespace MongoDB.Driver
20+
{
21+
// TODO: CSOT: Make it public when CSOT will be ready for GA
22+
internal sealed class CommitTransactionOptions
23+
{
24+
public CommitTransactionOptions(TimeSpan? timeout)
25+
{
26+
Timeout = Ensure.IsNullOrValidTimeout(timeout, nameof(timeout));
27+
}
28+
29+
public TimeSpan? Timeout { get; }
30+
}
31+
}
32+

src/MongoDB.Driver/Core/Bindings/CoreSession.cs

Lines changed: 29 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* Copyright 2018-present MongoDB Inc.
1+
/* Copyright 2010-present MongoDB Inc.
22
*
33
* Licensed under the Apache License, Version 2.0 (the "License");
44
* you may not use this file except in compliance with the License.
@@ -29,7 +29,7 @@ namespace MongoDB.Driver.Core.Bindings
2929
/// Represents a session.
3030
/// </summary>
3131
/// <seealso cref="MongoDB.Driver.Core.Bindings.ICoreSession" />
32-
public sealed class CoreSession : ICoreSession
32+
public sealed class CoreSession : ICoreSession, ICoreSessionInternal
3333
{
3434
// private fields
3535
#pragma warning disable CA2213 // Disposable fields should be disposed
@@ -141,12 +141,15 @@ public bool IsInTransaction
141141

142142
// public methods
143143
/// <inheritdoc />
144-
public void AbortTransaction(CancellationToken cancellationToken = default(CancellationToken))
144+
public void AbortTransaction(CancellationToken cancellationToken = default)
145+
=> ((ICoreSessionInternal)this).AbortTransaction(null, cancellationToken);
146+
147+
// TODO: CSOT: Make it public when CSOT will be ready for GA and add default value to cancellationToken parameter.
148+
void ICoreSessionInternal.AbortTransaction(AbortTransactionOptions options, CancellationToken cancellationToken)
145149
{
146150
EnsureAbortTransactionCanBeCalled(nameof(AbortTransaction));
147151

148-
// TODO: CSOT implement proper way to obtain the operationContext
149-
var operationContext = new OperationContext(null, cancellationToken);
152+
using var operationContext = new OperationContext(GetTimeout(options?.Timeout), cancellationToken);
150153
try
151154
{
152155
if (_currentTransaction.IsEmpty)
@@ -192,12 +195,15 @@ public bool IsInTransaction
192195
}
193196

194197
/// <inheritdoc />
195-
public async Task AbortTransactionAsync(CancellationToken cancellationToken = default(CancellationToken))
198+
public Task AbortTransactionAsync(CancellationToken cancellationToken = default)
199+
=> ((ICoreSessionInternal)this).AbortTransactionAsync(null, cancellationToken);
200+
201+
// TODO: CSOT: Make it public when CSOT will be ready for GA and add default value to cancellationToken parameter.
202+
async Task ICoreSessionInternal.AbortTransactionAsync(AbortTransactionOptions options, CancellationToken cancellationToken)
196203
{
197204
EnsureAbortTransactionCanBeCalled(nameof(AbortTransaction));
198205

199-
// TODO: CSOT implement proper way to obtain the operationContext
200-
var operationContext = new OperationContext(null, cancellationToken);
206+
using var operationContext = new OperationContext(GetTimeout(options?.Timeout), cancellationToken);
201207
try
202208
{
203209
if (_currentTransaction.IsEmpty)
@@ -292,12 +298,15 @@ public long AdvanceTransactionNumber()
292298
}
293299

294300
/// <inheritdoc />
295-
public void CommitTransaction(CancellationToken cancellationToken = default(CancellationToken))
301+
public void CommitTransaction(CancellationToken cancellationToken = default)
302+
=> ((ICoreSessionInternal)this).CommitTransaction(null, cancellationToken);
303+
304+
// TODO: CSOT: Make it public when CSOT will be ready for GA and add default value to cancellationToken parameter.
305+
void ICoreSessionInternal.CommitTransaction(CommitTransactionOptions options, CancellationToken cancellationToken)
296306
{
297307
EnsureCommitTransactionCanBeCalled(nameof(CommitTransaction));
298308

299-
// TODO: CSOT implement proper way to obtain the operationContext
300-
var operationContext = new OperationContext(null, cancellationToken);
309+
using var operationContext = new OperationContext(GetTimeout(options?.Timeout), cancellationToken);
301310
try
302311
{
303312
_isCommitTransactionInProgress = true;
@@ -329,12 +338,15 @@ public long AdvanceTransactionNumber()
329338
}
330339

331340
/// <inheritdoc />
332-
public async Task CommitTransactionAsync(CancellationToken cancellationToken = default(CancellationToken))
341+
public Task CommitTransactionAsync(CancellationToken cancellationToken = default)
342+
=> ((ICoreSessionInternal)this).CommitTransactionAsync(null, cancellationToken);
343+
344+
// TODO: CSOT: Make it public when CSOT will be ready for GA and add default value to cancellationToken parameter.
345+
async Task ICoreSessionInternal.CommitTransactionAsync(CommitTransactionOptions options, CancellationToken cancellationToken)
333346
{
334347
EnsureCommitTransactionCanBeCalled(nameof(CommitTransaction));
335348

336-
// TODO: CSOT implement proper way to obtain the operationContext
337-
var operationContext = new OperationContext(null, cancellationToken);
349+
using var operationContext = new OperationContext(GetTimeout(options?.Timeout), cancellationToken);
338350
try
339351
{
340352
_isCommitTransactionInProgress = true;
@@ -563,6 +575,9 @@ private async Task<TResult> ExecuteEndTransactionOnPrimaryAsync<TResult>(Operati
563575
}
564576
}
565577

578+
private TimeSpan? GetTimeout(TimeSpan? timeout)
579+
=> timeout ?? _options.DefaultTransactionOptions?.Timeout;
580+
566581
private TransactionOptions GetEffectiveTransactionOptions(TransactionOptions transactionOptions)
567582
{
568583
var readConcern = transactionOptions?.ReadConcern ?? _options.DefaultTransactionOptions?.ReadConcern ?? ReadConcern.Default;

src/MongoDB.Driver/Core/Bindings/CoreTransaction.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* Copyright 2018-present MongoDB Inc.
1+
/* Copyright 2010-present MongoDB Inc.
22
*
33
* Licensed under the Apache License, Version 2.0 (the "License");
44
* you may not use this file except in compliance with the License.
@@ -56,6 +56,8 @@ public CoreTransaction(long transactionNumber, TransactionOptions transactionOpt
5656
/// </value>
5757
public bool IsEmpty => _isEmpty;
5858

59+
internal OperationContext OperationContext { get; set; }
60+
5961
/// <summary>
6062
/// Gets the transaction state.
6163
/// </summary>
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
/* Copyright 2010-present MongoDB Inc.
2+
*
3+
* Licensed under the Apache License, Version 2.0 (the "License");
4+
* you may not use this file except in compliance with the License.
5+
* You may obtain a copy of the License at
6+
*
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* Unless required by applicable law or agreed to in writing, software
10+
* distributed under the License is distributed on an "AS IS" BASIS,
11+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
* See the License for the specific language governing permissions and
13+
* limitations under the License.
14+
*/
15+
16+
using System.Threading;
17+
using System.Threading.Tasks;
18+
19+
namespace MongoDB.Driver.Core.Bindings
20+
{
21+
// TODO: CSOT: Make it public when CSOT will be ready for GA
22+
internal static class ICoreSessionExtensions
23+
{
24+
// TODO: Merge these extension methods in ICoreSession interface on major release
25+
public static void AbortTransaction(this ICoreSession session, AbortTransactionOptions options, CancellationToken cancellationToken = default)
26+
{
27+
if (options == null || session.Options.DefaultTransactionOptions?.Timeout == options.Timeout)
28+
{
29+
session.AbortTransaction(cancellationToken);
30+
return;
31+
}
32+
33+
((ICoreSessionInternal)session).AbortTransaction(options, cancellationToken);
34+
}
35+
36+
public static Task AbortTransactionAsync(this ICoreSession session, AbortTransactionOptions options, CancellationToken cancellationToken = default)
37+
{
38+
if (options == null || session.Options.DefaultTransactionOptions?.Timeout == options.Timeout)
39+
{
40+
return session.AbortTransactionAsync(cancellationToken);
41+
}
42+
43+
return ((ICoreSessionInternal)session).AbortTransactionAsync(options, cancellationToken);
44+
}
45+
46+
public static void CommitTransaction(this ICoreSession session, CommitTransactionOptions options, CancellationToken cancellationToken = default)
47+
{
48+
if (options == null || session.Options.DefaultTransactionOptions?.Timeout == options.Timeout)
49+
{
50+
session.CommitTransaction(cancellationToken);
51+
return;
52+
}
53+
54+
((ICoreSessionInternal)session).CommitTransaction(options, cancellationToken);
55+
}
56+
57+
public static Task CommitTransactionAsync(this ICoreSession session, CommitTransactionOptions options, CancellationToken cancellationToken = default)
58+
{
59+
if (options == null || session.Options.DefaultTransactionOptions?.Timeout == options.Timeout)
60+
{
61+
return session.CommitTransactionAsync(cancellationToken);
62+
}
63+
64+
return ((ICoreSessionInternal)session).CommitTransactionAsync(options, cancellationToken);
65+
}
66+
}
67+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/* Copyright 2010-present MongoDB Inc.
2+
*
3+
* Licensed under the Apache License, Version 2.0 (the "License");
4+
* you may not use this file except in compliance with the License.
5+
* You may obtain a copy of the License at
6+
*
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* Unless required by applicable law or agreed to in writing, software
10+
* distributed under the License is distributed on an "AS IS" BASIS,
11+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
* See the License for the specific language governing permissions and
13+
* limitations under the License.
14+
*/
15+
16+
using System.Threading;
17+
using System.Threading.Tasks;
18+
19+
namespace MongoDB.Driver.Core.Bindings;
20+
21+
// TODO: Merge this interface into ICoreSession on major release
22+
internal interface ICoreSessionInternal
23+
{
24+
void AbortTransaction(AbortTransactionOptions options, CancellationToken cancellationToken = default);
25+
Task AbortTransactionAsync(AbortTransactionOptions options, CancellationToken cancellationToken = default);
26+
void CommitTransaction(CommitTransactionOptions options, CancellationToken cancellationToken = default);
27+
Task CommitTransactionAsync(CommitTransactionOptions options, CancellationToken cancellationToken = default);
28+
}

0 commit comments

Comments
 (0)