@@ -37,6 +37,67 @@ lazy_static! {
3737///
3838/// `ClientSession` instances are not thread safe or fork safe. They can only be used by one thread
3939/// 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.
40101#[ derive( Clone , Debug ) ]
41102pub struct ClientSession {
42103 cluster_time : Option < ClusterTime > ,
@@ -193,6 +254,10 @@ impl ClientSession {
193254 /// be passed into each operation within the transaction; otherwise, the operation will be
194255 /// executed outside of the transaction.
195256 ///
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+ ///
196261 /// Transactions are supported on MongoDB 4.0+. The Rust driver currently only supports
197262 /// transactions on replica sets.
198263 ///
@@ -276,6 +341,13 @@ impl ClientSession {
276341
277342 /// Commits the transaction that is currently active on this session.
278343 ///
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+ ///
279351 /// ```rust
280352 /// # use mongodb::{bson::{doc, Document}, error::Result, Client, ClientSession};
281353 /// #
@@ -344,14 +416,14 @@ impl ClientSession {
344416 /// # let coll = client.database("foo").collection::<Document>("bar");
345417 /// # let mut session = client.start_session(None).await?;
346418 /// session.start_transaction(None).await?;
347- /// match execute_transaction(coll, &mut session).await {
419+ /// match execute_transaction(& coll, &mut session).await {
348420 /// Ok(_) => session.commit_transaction().await?,
349421 /// Err(_) => session.abort_transaction().await?,
350422 /// }
351423 /// # Ok(())
352424 /// # }
353425 ///
354- /// async fn execute_transaction(coll: Collection, session: &mut ClientSession) -> Result<()> {
426+ /// async fn execute_transaction(coll: & Collection, session: &mut ClientSession) -> Result<()> {
355427 /// coll.insert_one_with_session(doc! { "x": 1 }, None, session).await?;
356428 /// coll.delete_one_with_session(doc! { "y": 2 }, None, session).await?;
357429 /// Ok(())
0 commit comments