-
Notifications
You must be signed in to change notification settings - Fork 24
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
DOCSP-37469: Add transactions page (#199)
(cherry picked from commit 8553e6d)
- Loading branch information
Showing
3 changed files
with
330 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,227 @@ | ||
.. _csharp-transactions: | ||
|
||
============ | ||
Transactions | ||
============ | ||
|
||
.. facet:: | ||
:name: genre | ||
:values: reference | ||
|
||
.. meta:: | ||
:keywords: code example, multi-document | ||
|
||
.. contents:: On this page | ||
:local: | ||
:backlinks: none | ||
:depth: 2 | ||
:class: singlecol | ||
|
||
Overview | ||
-------- | ||
|
||
In this guide, you can learn how to use the {+driver-long+} to perform | ||
**transactions**. :manual:`Transactions </core/transactions/>` allow | ||
you to run a series of operations that do not change any data until the | ||
transaction is committed. If any operation in the transaction returns an | ||
error, the driver cancels the transaction and discards all data changes | ||
before they ever become visible. | ||
|
||
In MongoDB, transactions run within logical **sessions**. A | ||
:manual:`session </reference/server-sessions/>` is a grouping of related | ||
read or write operations that you intend to run sequentially. Sessions | ||
enable :manual:`causal consistency | ||
</core/read-isolation-consistency-recency/#causal-consistency>` for a | ||
group of operations or allow you to execute operations in an | ||
:website:`ACID transaction </basics/acid-transactions>`. MongoDB | ||
guarantees that the data involved in your transaction operations remains | ||
consistent, even if the operations encounter unexpected errors. | ||
|
||
When using the {+driver-short+}, you can create a new session from a | ||
``MongoClient`` instance as an ``IClientSession`` type. We recommend that you reuse | ||
your client for multiple sessions and transactions instead of | ||
instantiating a new client each time. | ||
|
||
.. warning:: | ||
|
||
Use an ``IClientSession`` only with the ``MongoClient`` (or associated | ||
``MongoDatabase`` or ``MongoCollection``) that created it. Using an | ||
``IClientSession`` with a different ``MongoClient`` results in operation | ||
errors. | ||
|
||
Methods | ||
------- | ||
|
||
Create an ``IClientSession`` by using either the synchronous ``StartSession()`` or | ||
the asynchronous ``StartSessionAsync()`` method on your ``MongoClient`` instance. | ||
You can then modify the session state by using the method set | ||
provided by the ``IClientSession`` interface. Select from the following | ||
:guilabel:`Synchronous Methods` and :guilabel:`Asynchronous Methods` | ||
tabs to learn about the methods to manage your transaction: | ||
|
||
.. tabs:: | ||
|
||
.. tab:: Synchronous Methods | ||
:tabid: synchronous-methods | ||
|
||
.. list-table:: | ||
:widths: 40 60 | ||
:header-rows: 1 | ||
|
||
* - Method | ||
- Description | ||
|
||
* - ``StartTransaction()`` | ||
- | Starts a new transaction, configured with the given options, on | ||
this session. Throws an exception if there is already | ||
a transaction in progress for the session. To learn more about | ||
this method, see the :manual:`startTransaction() page | ||
</reference/method/Session.startTransaction/>` in the Server manual. | ||
| | ||
| **Parameter**: ``TransactionOptions`` (optional) | ||
|
||
* - ``AbortTransaction()`` | ||
- | Ends the active transaction for this session. Throws an exception | ||
if there is no active transaction for the session or the | ||
transaction has been committed or ended. To learn more about | ||
this method, see the :manual:`abortTransaction() page | ||
</reference/method/Session.abortTransaction/>` in the Server manual. | ||
| | ||
| **Parameter**: ``CancellationToken`` | ||
|
||
* - ``CommitTransaction()`` | ||
- | Commits the active transaction for this session. Throws an exception | ||
if there is no active transaction for the session or if the | ||
transaction was ended. To learn more about | ||
this method, see the :manual:`commitTransaction() page | ||
</reference/method/Session.commitTransaction/>` in the Server manual. | ||
| | ||
| **Parameter**: ``CancellationToken`` | ||
|
||
* - ``WithTransaction()`` | ||
- | Starts a transaction on this session and runs the given callback. To | ||
learn more about this method, see the :manual:`withTransaction() page | ||
</reference/method/Session.withTransaction/>` in the Server manual. | ||
|
||
.. warning:: Handling Exceptions | ||
|
||
When catching exceptions within the callback function used by | ||
``WithTransaction()``, you **must** rethrow the exception before | ||
exiting the try-catch block. Failing to do so can result in an | ||
infinite loop. For further details on how to handle exceptions in this | ||
case, see :manual:`Transactions </core/transactions/>` in the Server | ||
manual and select :guilabel:`C#` from the language dropdown to view | ||
the example. | ||
|
||
| | ||
| **Parameters**: ``Func <IClientSessionHandle, CancellationToken, Task<TResult>>``, ``TransactionOptions``, ``CancellationToken`` | ||
| **Return Type**: ``Task <TResult>`` | ||
|
||
.. tab:: Asynchronous Methods | ||
:tabid: asynchronous-methods | ||
|
||
.. list-table:: | ||
:widths: 40 60 | ||
:header-rows: 1 | ||
|
||
* - Method | ||
- Description | ||
|
||
* - ``StartTransaction()`` | ||
- | Starts a new transaction, configured with the given options, on | ||
this session. Throws an exception if there is already | ||
a transaction in progress for the session. To learn more about | ||
this method, see the :manual:`startTransaction() page | ||
</reference/method/Session.startTransaction/>` in the Server manual. | ||
| | ||
| **Parameter**: ``TransactionOptions`` (optional) | ||
|
||
* - ``AbortTransactionAsync()`` | ||
- | Ends the active transaction for this session. Throws an exception | ||
if there is no active transaction for the session or the | ||
transaction has been committed or ended. To learn more about | ||
this method, see the :manual:`abortTransaction() page | ||
</reference/method/Session.abortTransaction/>` in the Server manual. | ||
| | ||
| **Parameter**: ``CancellationToken`` | ||
| **Return Type**: ``Task`` | ||
|
||
|
||
* - ``CommitTransactionAsync()`` | ||
- | Commits the active transaction for this session. Throws an | ||
exception if there is no active transaction for the session or if the | ||
transaction was ended. To learn more about | ||
this method, see the :manual:`commitTransaction() page | ||
</reference/method/Session.commitTransaction/>` in the Server manual. | ||
| | ||
| **Parameter**: ``CancellationToken`` | ||
| **Return Type**: ``Task`` | ||
|
||
* - ``WithTransactionAsync()`` | ||
- | Starts a transaction on this session and runs the given callback. To | ||
learn more about this method, see the :manual:`withTransaction() page | ||
</reference/method/Session.withTransaction/>` in the Server manual. | ||
|
||
.. warning:: Handling Exceptions | ||
|
||
When catching exceptions within the callback function used by | ||
``WithTransactionAsync()``, you **must** rethrow the exception | ||
before exiting the try-catch block. Failing to do so can result in an | ||
infinite loop. For further details on how to handle exceptions in this | ||
case, see :manual:`Transactions </core/transactions/>` in the Server | ||
manual and select :guilabel:`C#` from the language dropdown to view | ||
the example. | ||
|
||
| | ||
| **Parameters**: ``Func <IClientSessionHandle, CancellationToken, Task<TResult>>``, ``TransactionOptions``, ``CancellationToken`` | ||
| **Return Type**: ``Task <TResult>`` | ||
|
||
Example | ||
------- | ||
|
||
This example shows how you can create a session, create a | ||
transaction, and insert documents into multiple collections within the transaction | ||
through the following steps: | ||
|
||
1. Create a session from the client by using the ``StartSession()`` method. | ||
#. Use the ``StartTransaction()`` method to start a transaction. | ||
#. Insert documents into the ``books`` and ``films`` collections. | ||
#. Commit the transaction by using the ``CommitTransaction()`` method. | ||
|
||
.. io-code-block:: | ||
|
||
.. input:: /includes/fundamentals/code-examples/Transaction.cs | ||
:language: csharp | ||
:dedent: | ||
:start-after: begin-transaction | ||
:end-before: end-transaction | ||
|
||
.. output:: | ||
:language: console | ||
:visible: false | ||
|
||
Successfully committed transaction! | ||
|
||
Additional Information | ||
---------------------- | ||
|
||
To learn more about the concepts mentioned in this guide, see the | ||
following pages in the Server manual: | ||
|
||
- :manual:`Transactions </core/transactions/>` | ||
- :manual:`Server Sessions </reference/server-sessions/>` | ||
- :manual:`Read Isolation, Consistency, and Recency </core/read-isolation-consistency-recency/#causal-consistency>` | ||
|
||
API Documentation | ||
~~~~~~~~~~~~~~~~~ | ||
|
||
To learn more about any of the types or methods discussed in this | ||
guide, see the following API Documentation: | ||
|
||
- `IClientSession <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.IClientSession.html>`__ | ||
- `MongoClient <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.MongoClient.html>`__ | ||
- `StartTransaction() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.IClientSession.StartTransaction.html>`__ | ||
- `AbortTransaction() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.IClientSession.AbortTransaction.html>`__ / `AbortTransactionAsync() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.IClientSession.AbortTransactionAsync.html>`__ | ||
- `CommitTransaction() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.IClientSession.CommitTransaction.html>`__ / `CommitTransactionAsync() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.IClientSession.CommitTransactionAsync.html>`__ | ||
- `WithTransaction() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.IClientSession.WithTransaction.html>`__ / `WithTransactionAsync() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.IClientSession.WithTransactionAsync.html>`__ | ||
- `TransactionOptions <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.TransactionOptions.html>`__ |
101 changes: 101 additions & 0 deletions
101
source/includes/fundamentals/code-examples/Transaction.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
using MongoDB.Bson; | ||
using MongoDB.Bson.Serialization.Attributes; | ||
using MongoDB.Bson.Serialization.Conventions; | ||
using MongoDB.Driver; | ||
|
||
public class BookTransaction | ||
{ | ||
// Replace with your connection string | ||
private const string MongoConnectionString = "<YOUR_CONNECTION_STRING>"; | ||
|
||
public static void Main(string[] args) | ||
{ | ||
// Establishes the connection to MongoDB and accesses the library database | ||
var mongoClient = new MongoClient(MongoConnectionString); | ||
var database = mongoClient.GetDatabase("library"); | ||
|
||
// Cleans up the collections we'll be using | ||
Setup(database); | ||
|
||
// begin-transaction | ||
var books = database.GetCollection<Book>("books"); | ||
var films = database.GetCollection<Film>("films"); | ||
|
||
// Begins transaction | ||
using (var session = mongoClient.StartSession()) | ||
{ | ||
session.StartTransaction(); | ||
|
||
try | ||
{ | ||
// Creates sample data | ||
var book = new Book | ||
{ | ||
Title = "Beloved", | ||
Author = "Toni Morrison", | ||
InStock = true | ||
}; | ||
|
||
var film = new Film | ||
{ | ||
Title = "Star Wars", | ||
Director = "George Lucas", | ||
InStock = true | ||
}; | ||
|
||
// Inserts sample data | ||
books.InsertOne(session, book); | ||
films.InsertOne(session, film); | ||
|
||
// Commits our transaction | ||
session.CommitTransaction(); | ||
} | ||
catch (Exception e) | ||
{ | ||
Console.WriteLine("Error writing to MongoDB: " + e.Message); | ||
return; | ||
} | ||
|
||
// Prints a success message if no error thrown | ||
Console.WriteLine("Successfully committed transaction!"); | ||
} | ||
// end-transaction | ||
} | ||
|
||
public static void Setup(IMongoDatabase database) | ||
{ | ||
database.DropCollection("books"); | ||
database.CreateCollection("books"); | ||
|
||
database.DropCollection("films"); | ||
database.CreateCollection("films"); | ||
} | ||
} | ||
|
||
public class Book | ||
{ | ||
public ObjectId Id { get; set; } | ||
|
||
[BsonElement("title")] | ||
public string Title { get; set; } | ||
|
||
[BsonElement("author")] | ||
public string Author { get; set; } | ||
|
||
[BsonElement("inStock")] | ||
public bool InStock { get; set; } | ||
} | ||
|
||
public class Film | ||
{ | ||
public ObjectId Id { get; set; } | ||
|
||
[BsonElement("title")] | ||
public string Title { get; set; } | ||
|
||
[BsonElement("director")] | ||
public string Director { get; set; } | ||
|
||
[BsonElement("inStock")] | ||
public bool InStock { get; set; } | ||
} |