@@ -37,6 +37,67 @@ lazy_static! {
37
37
///
38
38
/// `ClientSession` instances are not thread safe or fork safe. They can only be used by one thread
39
39
/// or process at a time.
40
+ ///
41
+ /// ## Transactions
42
+ /// Transactions are used to execute a series of operations across multiple documents and
43
+ /// collections atomically. For more information about when and how to use transactions in MongoDB,
44
+ /// see the [manual](https://docs.mongodb.com/manual/core/transactions/).
45
+ ///
46
+ /// Replica set transactions are supported on MongoDB 4.0+. Transactions are associated with a
47
+ /// `ClientSession`. To begin a transaction, call [`ClientSession::start_transaction`] on a
48
+ /// `ClientSession`. The `ClientSession` must be passed to operations to be executed within the
49
+ /// transaction.
50
+ ///
51
+ /// ```rust
52
+ /// use mongodb::{
53
+ /// bson::doc,
54
+ /// error::{Result, TRANSIENT_TRANSACTION_ERROR, UNKNOWN_TRANSACTION_COMMIT_RESULT},
55
+ /// options::{Acknowledgment, ReadConcern, TransactionOptions, WriteConcern},
56
+ /// # Client,
57
+ /// ClientSession,
58
+ /// Collection,
59
+ /// };
60
+ ///
61
+ /// # async fn do_stuff() -> Result<()> {
62
+ /// # let client = Client::with_uri_str("mongodb://example.com").await?;
63
+ /// # let coll = client.database("foo").collection("bar");
64
+ /// let mut session = client.start_session(None).await?;
65
+ /// let options = TransactionOptions::builder()
66
+ /// .read_concern(ReadConcern::majority())
67
+ /// .write_concern(WriteConcern::builder().w(Acknowledgment::Majority).build())
68
+ /// .build();
69
+ /// session.start_transaction(options).await?;
70
+ /// // A "TransientTransactionError" label indicates that the entire transaction can be retried
71
+ /// // with a reasonable expectation that it will succeed.
72
+ /// while let Err(error) = execute_transaction(&coll, &mut session).await {
73
+ /// if !error.contains_label(TRANSIENT_TRANSACTION_ERROR) {
74
+ /// break;
75
+ /// }
76
+ /// }
77
+ /// # Ok(())
78
+ /// # }
79
+ ///
80
+ /// async fn execute_transaction(coll: &Collection, session: &mut ClientSession) -> Result<()> {
81
+ /// coll.insert_one_with_session(doc! { "x": 1 }, None, session).await?;
82
+ /// coll.delete_one_with_session(doc! { "y": 2 }, None, session).await?;
83
+ /// // An "UnknownTransactionCommitResult" label indicates that it is unknown whether the
84
+ /// // commit has satisfied the write concern associated with the transaction. If an error
85
+ /// // with this label is returned, it is safe to retry the commit until the write concern is
86
+ /// // satisfied or an error without the label is returned.
87
+ /// loop {
88
+ /// let result = session.commit_transaction().await;
89
+ /// if let Err(ref error) = result {
90
+ /// if error.contains_label(UNKNOWN_TRANSACTION_COMMIT_RESULT) {
91
+ /// continue;
92
+ /// }
93
+ /// }
94
+ /// result?
95
+ /// }
96
+ /// }
97
+ /// ```
98
+ // TODO RUST-122 Remove this note and adjust the above description to indicate that sharded
99
+ // transactions are supported on 4.2+
100
+ /// Note: the driver does not currently support transactions on sharded clusters.
40
101
#[ derive( Clone , Debug ) ]
41
102
pub struct ClientSession {
42
103
cluster_time : Option < ClusterTime > ,
@@ -193,6 +254,10 @@ impl ClientSession {
193
254
/// be passed into each operation within the transaction; otherwise, the operation will be
194
255
/// executed outside of the transaction.
195
256
///
257
+ /// Errors returned from operations executed within a transaction may include a
258
+ /// [`crate::error::TRANSIENT_TRANSACTION_ERROR`] label. This label indicates that the entire
259
+ /// transaction can be retried with a reasonable expectation that it will succeed.
260
+ ///
196
261
/// Transactions are supported on MongoDB 4.0+. The Rust driver currently only supports
197
262
/// transactions on replica sets.
198
263
///
@@ -276,6 +341,13 @@ impl ClientSession {
276
341
277
342
/// Commits the transaction that is currently active on this session.
278
343
///
344
+ ///
345
+ /// This method may return an error with a [`crate::error::UNKNOWN_TRANSACTION_COMMIT_RESULT`]
346
+ /// label. This label indicates that it is unknown whether the commit has satisfied the write
347
+ /// concern associated with the transaction. If an error with this label is returned, it is
348
+ /// safe to retry the commit until the write concern is satisfied or an error without the label
349
+ /// is returned.
350
+ ///
279
351
/// ```rust
280
352
/// # use mongodb::{bson::{doc, Document}, error::Result, Client, ClientSession};
281
353
/// #
@@ -344,14 +416,14 @@ impl ClientSession {
344
416
/// # let coll = client.database("foo").collection::<Document>("bar");
345
417
/// # let mut session = client.start_session(None).await?;
346
418
/// session.start_transaction(None).await?;
347
- /// match execute_transaction(coll, &mut session).await {
419
+ /// match execute_transaction(& coll, &mut session).await {
348
420
/// Ok(_) => session.commit_transaction().await?,
349
421
/// Err(_) => session.abort_transaction().await?,
350
422
/// }
351
423
/// # Ok(())
352
424
/// # }
353
425
///
354
- /// async fn execute_transaction(coll: Collection, session: &mut ClientSession) -> Result<()> {
426
+ /// async fn execute_transaction(coll: & Collection, session: &mut ClientSession) -> Result<()> {
355
427
/// coll.insert_one_with_session(doc! { "x": 1 }, None, session).await?;
356
428
/// coll.delete_one_with_session(doc! { "y": 2 }, None, session).await?;
357
429
/// Ok(())
0 commit comments