1MONGOC_CLIENT_SESSION_START_TRANSACTlIiMObONmN(oG3nO)gCo_cCLIENT_SESSION_START_TRANSACTION(3)
2
3
4

SYNOPSIS

6          bool
7          mongoc_client_session_start_transaction (mongoc_client_session_t *session,
8                                                   const mongoc_transaction_opt_t *opts,
9                                                   bson_error_t *error);
10
11       Start a multi-document transaction for all following operations in this
12       session. Any options  provided  in  opts  override  options  passed  to
13       mongoc_session_opts_set_default_transaction_opts(),  and options inher‐
14       ited from the mongoc_client_t. The opts argument is copied and  can  be
15       freed after calling this function.
16
17       The        transaction        must        be       completed       with
18       mongoc_client_session_commit_transaction()                           or
19       mongoc_client_session_abort_transaction().  An  in-progress transaction
20       is automatically aborted by mongoc_client_session_destroy().
21

PARAMETERS

23session: A mongoc_client_session_t.
24
25opts: A mongoc_transaction_opt_t or NULL.
26
27error: An optional location for a bson_error_t or NULL.
28

RETURN

30       Returns true if the transaction was started. Returns false and sets er‐
31       ror  if  there are invalid arguments, such as a session with a transac‐
32       tion already in progress.
33

EXAMPLE

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

AUTHOR

224       MongoDB, Inc
225
227       2017-present, MongoDB, Inc
228
229
230
231
2321.25.1                           NovM0O8N,GO2C0_2C3LIENT_SESSION_START_TRANSACTION(3)
Impressum