1MONGOC_TRANSACTION_OPT_T(3)        libmongoc       MONGOC_TRANSACTION_OPT_T(3)
2
3
4
5          #include <mongoc/mongoc.h>
6
7          typedef struct _mongoc_transaction_opt_t mongoc_transaction_opt_t;
8

SYNOPSIS

10       Options for starting a multi-document transaction.
11
12       When  a session is first created with mongoc_client_start_session(), it
13       inherits from the client the read  concern,  write  concern,  and  read
14       preference  with  which to start transactions. Each of these fields can
15       be overridden independently.  Create  a  mongoc_transaction_opt_t  with
16       mongoc_transaction_opts_new(), and pass a non-NULL option to any of the
17       mongoc_transaction_opt_t setter functions:
18
19mongoc_transaction_opts_set_read_concern()
20
21mongoc_transaction_opts_set_write_concern()
22
23mongoc_transaction_opts_set_read_prefs()
24
25       Pass       the       resulting       transaction       options       to
26       mongoc_client_session_start_transaction(). Each field set in the trans‐
27       action options overrides the inherited client configuration.
28

EXAMPLE

30       example-transaction.c
31
32          /* gcc example-transaction.c -o example-transaction \
33           *     $(pkg-config --cflags --libs libmongoc-1.0) */
34
35          /* ./example-transaction [CONNECTION_STRING] */
36
37          #include <stdio.h>
38          #include <mongoc/mongoc.h>
39
40
41          int
42          main (int argc, char *argv[])
43          {
44             int exit_code = EXIT_FAILURE;
45
46             mongoc_client_t *client = NULL;
47             mongoc_database_t *database = NULL;
48             mongoc_collection_t *collection = NULL;
49             mongoc_client_session_t *session = NULL;
50             mongoc_session_opt_t *session_opts = NULL;
51             mongoc_transaction_opt_t *default_txn_opts = NULL;
52             mongoc_transaction_opt_t *txn_opts = NULL;
53             mongoc_read_concern_t *read_concern = NULL;
54             mongoc_write_concern_t *write_concern = NULL;
55             const char *uri_string = "mongodb://127.0.0.1/?appname=transaction-example";
56             mongoc_uri_t *uri;
57             bson_error_t error;
58             bson_t *doc = NULL;
59             bson_t *insert_opts = NULL;
60             int32_t i;
61             int64_t start;
62             bson_t reply = BSON_INITIALIZER;
63             char *reply_json;
64             bool r;
65
66             mongoc_init ();
67
68             if (argc > 1) {
69                uri_string = argv[1];
70             }
71
72             uri = mongoc_uri_new_with_error (uri_string, &error);
73             if (!uri) {
74                MONGOC_ERROR ("failed to parse URI: %s\n"
75                              "error message:       %s\n",
76                              uri_string,
77                              error.message);
78                goto done;
79             }
80
81             client = mongoc_client_new_from_uri (uri);
82             if (!client) {
83                goto done;
84             }
85
86             mongoc_client_set_error_api (client, 2);
87             database = mongoc_client_get_database (client, "example-transaction");
88
89             /* inserting into a nonexistent collection normally creates it, but a
90              * collection can't be created in a transaction; create it now */
91             collection =
92                mongoc_database_create_collection (database, "collection", NULL, &error);
93
94             if (!collection) {
95                /* code 48 is NamespaceExists, see error_codes.err in mongodb source */
96                if (error.code == 48) {
97                   collection = mongoc_database_get_collection (database, "collection");
98                } else {
99                   MONGOC_ERROR ("Failed to create collection: %s", error.message);
100                   goto done;
101                }
102             }
103
104             /* a transaction's read preferences, read concern, and write concern can be
105              * set on the client, on the default transaction options, or when starting
106              * the transaction. for the sake of this example, set read concern on the
107              * default transaction options. */
108             default_txn_opts = mongoc_transaction_opts_new ();
109             read_concern = mongoc_read_concern_new ();
110             mongoc_read_concern_set_level (read_concern, "snapshot");
111             mongoc_transaction_opts_set_read_concern (default_txn_opts, read_concern);
112             session_opts = mongoc_session_opts_new ();
113             mongoc_session_opts_set_default_transaction_opts (session_opts,
114                                                               default_txn_opts);
115
116             session = mongoc_client_start_session (client, session_opts, &error);
117             if (!session) {
118                MONGOC_ERROR ("Failed to start session: %s", error.message);
119                goto done;
120             }
121
122             /* in this example, set write concern when starting the transaction */
123             txn_opts = mongoc_transaction_opts_new ();
124             write_concern = mongoc_write_concern_new ();
125             mongoc_write_concern_set_wmajority (write_concern, 1000 /* wtimeout */);
126             mongoc_transaction_opts_set_write_concern (txn_opts, write_concern);
127
128             insert_opts = bson_new ();
129             if (!mongoc_client_session_append (session, insert_opts, &error)) {
130                MONGOC_ERROR ("Could not add session to opts: %s", error.message);
131                goto done;
132             }
133
134          retry_transaction:
135             r = mongoc_client_session_start_transaction (session, txn_opts, &error);
136             if (!r) {
137                MONGOC_ERROR ("Failed to start transaction: %s", error.message);
138                goto done;
139             }
140
141             /* insert two documents - on error, retry the whole transaction */
142             for (i = 0; i < 2; i++) {
143                doc = BCON_NEW ("_id", BCON_INT32 (i));
144                bson_destroy (&reply);
145                r = mongoc_collection_insert_one (
146                   collection, doc, insert_opts, &reply, &error);
147
148                bson_destroy (doc);
149
150                if (!r) {
151                   MONGOC_ERROR ("Insert failed: %s", error.message);
152                   mongoc_client_session_abort_transaction (session, NULL);
153
154                   /* a network error, primary failover, or other temporary error in a
155                    * transaction includes {"errorLabels": ["TransientTransactionError"]},
156                    * meaning that trying the entire transaction again may succeed
157                    */
158                   if (mongoc_error_has_label (&reply, "TransientTransactionError")) {
159                      goto retry_transaction;
160                   }
161
162                   goto done;
163                }
164
165                reply_json = bson_as_json (&reply, NULL);
166                printf ("%s\n", reply_json);
167                bson_free (reply_json);
168             }
169
170             /* in case of transient errors, retry for 5 seconds to commit transaction */
171             start = bson_get_monotonic_time ();
172             while (bson_get_monotonic_time () - start < 5 * 1000 * 1000) {
173                bson_destroy (&reply);
174                r = mongoc_client_session_commit_transaction (session, &reply, &error);
175                if (r) {
176                   /* success */
177                   break;
178                } else {
179                   MONGOC_ERROR ("Warning: commit failed: %s", error.message);
180                   if (mongoc_error_has_label (&reply, "TransientTransactionError")) {
181                      goto retry_transaction;
182                   } else if (mongoc_error_has_label (&reply,
183                                                      "UnknownTransactionCommitResult")) {
184                      /* try again to commit */
185                      continue;
186                   }
187
188                   /* unrecoverable error trying to commit */
189                   break;
190                }
191             }
192
193             exit_code = EXIT_SUCCESS;
194
195          done:
196             bson_destroy (&reply);
197             bson_destroy (insert_opts);
198             mongoc_write_concern_destroy (write_concern);
199             mongoc_read_concern_destroy (read_concern);
200             mongoc_transaction_opts_destroy (txn_opts);
201             mongoc_transaction_opts_destroy (default_txn_opts);
202             mongoc_client_session_destroy (session);
203             mongoc_collection_destroy (collection);
204             mongoc_database_destroy (database);
205             mongoc_uri_destroy (uri);
206             mongoc_client_destroy (client);
207
208             mongoc_cleanup ();
209
210             return exit_code;
211          }
212
213

AUTHOR

215       MongoDB, Inc
216
218       2017-present, MongoDB, Inc
219
220
221
222
2231.25.1                           Nov 08, 2023      MONGOC_TRANSACTION_OPT_T(3)
Impressum