mongodb/operation/
commit_transaction.rs1use std::time::Duration;
2
3use crate::bson::rawdoc;
4
5use crate::{
6 bson_compat::{cstr, CStr},
7 cmap::{Command, RawCommandResponse, StreamDescription},
8 error::Result,
9 operation::{append_options_to_raw_document, OperationWithDefaults, Retryability},
10 options::{Acknowledgment, TransactionOptions, WriteConcern},
11};
12
13use super::{ExecutionContext, WriteConcernOnlyBody};
14
15pub(crate) struct CommitTransaction {
16 options: Option<TransactionOptions>,
17}
18
19impl CommitTransaction {
20 pub(crate) fn new(options: Option<TransactionOptions>) -> Self {
21 Self { options }
22 }
23}
24
25impl OperationWithDefaults for CommitTransaction {
26 type O = ();
27
28 const NAME: &'static CStr = cstr!("commitTransaction");
29
30 fn build(&mut self, _description: &StreamDescription) -> Result<Command> {
31 let mut body = rawdoc! {
32 Self::NAME: 1,
33 };
34
35 append_options_to_raw_document(&mut body, self.options.as_ref())?;
36
37 Ok(Command::new(Self::NAME, "admin", body))
38 }
39
40 fn handle_response<'a>(
41 &'a self,
42 response: &RawCommandResponse,
43 _context: ExecutionContext<'a>,
44 ) -> Result<Self::O> {
45 let response: WriteConcernOnlyBody = response.body()?;
46 response.validate()
47 }
48
49 fn write_concern(&self) -> Option<&WriteConcern> {
50 self.options
51 .as_ref()
52 .and_then(|opts| opts.write_concern.as_ref())
53 }
54
55 fn retryability(&self) -> Retryability {
56 Retryability::Write
57 }
58
59 fn update_for_retry(&mut self) {
63 let options = self
64 .options
65 .get_or_insert_with(|| TransactionOptions::builder().build());
66 match &mut options.write_concern {
67 Some(write_concern) => {
68 write_concern.w = Some(Acknowledgment::Majority);
69 if write_concern.w_timeout.is_none() {
70 write_concern.w_timeout = Some(Duration::from_millis(10000));
71 }
72 }
73 None => {
74 options.write_concern = Some(
75 WriteConcern::builder()
76 .w(Acknowledgment::Majority)
77 .w_timeout(Duration::from_millis(10000))
78 .build(),
79 );
80 }
81 }
82 }
83
84 #[cfg(feature = "opentelemetry")]
85 type Otel = crate::otel::Witness<Self>;
86}
87
88#[cfg(feature = "opentelemetry")]
89impl crate::otel::OtelInfoDefaults for CommitTransaction {
90 fn target(&self) -> crate::otel::OperationTarget<'_> {
91 crate::otel::OperationTarget::ADMIN
92 }
93}