1MONGOC_TRANSACTION_OPT_T(3)        libmongoc       MONGOC_TRANSACTION_OPT_T(3)
2
3
4

NAME

6       mongoc_transaction_opt_t - mongoc_transaction_opt_t
7
8          #include <mongoc/mongoc.h>
9
10          typedef struct _mongoc_transaction_opt_t mongoc_transaction_opt_t;
11

SYNOPSIS

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

EXAMPLE

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

AUTHOR

218       MongoDB, Inc
219
221       2017-present, MongoDB, Inc
222
223
224
225
2261.16.2                           Feb 25, 2020      MONGOC_TRANSACTION_OPT_T(3)
Impressum