-
Notifications
You must be signed in to change notification settings - Fork 67
SWIFT-423 Provide transactions guide for docs #444
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or 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 hidden or 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 hidden or 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,90 @@ | ||
| # Swift Driver Transactions Guide | ||
|
|
||
| `MongoSwift` 1.0.0 added support for [transactions](https://docs.mongodb.com/manual/core/transactions/), which allow applications to use to execute multiple read and write operations atomically across multiple documents and/or collections. Transactions reduce the need for complicated application logic when operating on several different documents simultaneously; however, because operations on single documents are always atomic, transactions are often not necessary. | ||
|
|
||
| Transactions in the driver must be started on a `ClientSession` using `startTransaction()`. The session must then be passed to each operation in the transaction. If the session is not passed to an operation, said operation will be executed outside the context of the transaction. Transactions must be committed or aborted using `commitTransaction()` or `abortTransaction()`, respectively. Ending a session *aborts* all in-progress transactions. | ||
|
|
||
| **Note**: Transactions only work with MongoDB replica sets (v4.0+) and sharded clusters (v4.2+). | ||
|
|
||
| ## Examples | ||
|
|
||
| ### Transaction that Atomically Moves a `Document` from One `MongoCollection` to Another | ||
patrickfreed marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| The transaction below atomically deletes the document `{ "hello": "world" }` from the collection `test.src` and inserts the document in the collection `test.dest`. This ensures that the document exists in either `test.src` or `test.dest`, but not both or neither. Executing the delete and insert non-atomically raises the following issues: | ||
| - A race between `deleteOne()` and `insertOne()` where the document does not exist in either collection. | ||
| - If `deleteOne()` fails and `insertOne()` succeeds, the document exists in both collections. | ||
| - If `deleteOne()` succeeds and `insertOne()` fails, the document does not exist in either collection. | ||
|
|
||
| ```swift | ||
| let client = try MongoClient(using: elg) | ||
| let session = client.startSession() | ||
|
|
||
| let db = client.db("test") | ||
| let srcColl = db.collection("src") | ||
| let destColl = db.collection("dest") | ||
| let docToMove: Document = ["hello": "world"] | ||
|
|
||
| session.startTransaction().flatMap { _ in | ||
| srcColl.deleteOne(docToMove, session: session) | ||
| }.flatMap { _ in | ||
| destColl.insertOne(docToMove, session: session) | ||
| }.flatMap { _ in | ||
| session.commitTransaction() | ||
| }.whenFailure { error in | ||
| session.abortTransaction() | ||
| // handle error | ||
| } | ||
| ``` | ||
|
|
||
| ### Transaction with Default Transaction Options | ||
patrickfreed marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| The default transaction options specified below apply to any transaction started on the session. | ||
|
|
||
| ```swift | ||
| let txnOpts = TransactionOptions( | ||
| maxCommitTimeMS: 30, | ||
| readConcern: ReadConcern(.local), | ||
| readPreference: .primaryPreferred, | ||
| writeConcern: try WriteConcern(w: .majority) | ||
| ) | ||
|
|
||
| let client = try MongoClient(using: elg) | ||
| let session = client.startSession(options: ClientSessionOptions(defaultTransactionOptions: txnOpts)) | ||
|
|
||
| session.startTransaction().flatMap { _ in | ||
| // do something | ||
| }.flatMap { _ in | ||
| session.commitTransaction() | ||
| }.whenFailure { error in | ||
| session.abortTransaction() | ||
| // handle error | ||
| } | ||
| ``` | ||
|
|
||
| ### Transaction with Custom Transaction Options | ||
|
|
||
| **Note**:: Any transaction options provided directly to `startTransaction()` override the default transaction options for the session. More so, the default transaction options for the session override any options inherited from the client. | ||
|
|
||
| ```swift | ||
| let client = try MongoClient(using: elg) | ||
| let session = client.startSession() | ||
|
|
||
| let txnOpts = TransactionOptions( | ||
| maxCommitTimeMS: 30, | ||
| readConcern: ReadConcern(.local), | ||
| readPreference: .primaryPreferred, | ||
| writeConcern: try WriteConcern(w: .majority) | ||
| ) | ||
|
|
||
| session.startTransaction(options: txnOpts).flatMap { _ in | ||
| // do something | ||
| }.flatMap { _ in | ||
| session.commitTransaction() | ||
| }.whenFailure { error in | ||
| session.abortTransaction() | ||
| // handle error | ||
| } | ||
| ``` | ||
|
|
||
| ## See Also | ||
| - [MongoDB Transactions documentation](https://docs.mongodb.com/manual/core/transactions/) | ||
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.