1MONGOC_CLIENT_SESSION_WITH_TRANSACTIlOiNbM(mO3oN)nGgOoCc_CLIENT_SESSION_WITH_TRANSACTION(3)
2
3
4
6 mongoc_client_session_with_transaction - mongoc_client_ses‐
7 sion_with_transaction()
8
10 bool
11 mongoc_client_session_with_transaction (mongoc_client_session_t *session,
12 mongoc_client_session_with_transaction_cb_t cb,
13 const mongoc_transaction_opt_t *opts,
14 void *ctx,
15 bson_t *reply,
16 bson_error_t *error);
17
18 This method will start a new transaction on session, run cb, and then
19 commit the transaction. If it cannot commit the transaction, the entire
20 sequence may be retried, and cb may be run multiple times. ctx will be
21 passed to cb each time it is called.
22
23 This method has an internal time limit of 120 seconds, and will retry
24 until that time limit is reached. This timeout is not configurable.
25
26 cb should not attempt to start new transactions, but should simply run
27 operations meant to be contained within a transaction. The cb does not
28 need to commit transactions; this is handled by the mongoc_client_ses‐
29 sion_with_transaction. If cb does commit or abort a transaction, how‐
30 ever, this method will return without taking further action.
31
32 The parameter reply is initialized even upon failure to simplify memory
33 management.
34
36 • session: A mongoc_client_session_t.
37
38 • cb: A mongoc_client_session_with_transaction_cb_t callback, which
39 will run inside of a new transaction on the session. See example be‐
40 low.
41
42 • opts: An optional mongoc_transaction_opt_t.
43
44 • ctx: A void*. This user-provided data will be passed to cb.
45
46 • reply: An optional location to initialize a bson_t or NULL. This
47 should be on the stack.
48
49 • error: An optional location for a bson_error_t or NULL.
50
52 Returns true if the transaction was completed successfully. Otherwise,
53 returns false in case of failure. In cases of failure error will also
54 be set, except if the passed-in cb fails without setting error. If a
55 non-NULL reply is passed in, reply will be set to the value of the last
56 server response, except if the passed-in cb fails without setting a re‐
57 ply.
58
60 Use with_transaction() to run a callback within a transaction
61
62 /* gcc example-with-transaction-cb.c -o example-with-transaction-cb $(pkg-config
63 * --cflags --libs libmongoc-1.0) */
64
65 /* ./example-with-transaction-cb [CONNECTION_STRING] */
66
67 #include <mongoc/mongoc.h>
68 #include <stdio.h>
69 #include <stdlib.h>
70
71 /*
72 * We pass this context object to mongoc_client_session_with_transaction() along
73 * with our callback function. The context object will be passed to our callback
74 * function when it runs, so we can access it.
75 */
76 typedef struct {
77 mongoc_collection_t *collection;
78 bson_t *insert_opts;
79 } ctx_t;
80
81 /*
82 * We pass this method as the callback to
83 * mongoc_client_session_with_transaction(). The insert that this method
84 * performs will happen inside of a new transaction.
85 */
86 bool
87 create_and_insert_doc (mongoc_client_session_t *session,
88 void *ctx,
89 bson_t **reply, /* out param for our server reply */
90 bson_error_t *error)
91 {
92 /*
93 * mongoc_collection_insert_one requires an uninitialized, stack-allocated
94 * bson_t to receive the update result
95 */
96 bson_t local_reply;
97 bson_t *doc = NULL;
98 ctx_t *data = NULL;
99 bool retval;
100
101 /*
102 * Create a new bson document - { id: 1 }
103 */
104 doc = BCON_NEW ("_id", BCON_INT32 (1));
105
106 printf (
107 "Running the user-defined callback in a newly created transaction...\n");
108 data = (ctx_t *) ctx;
109 retval = mongoc_collection_insert_one (
110 data->collection, doc, data->insert_opts, &local_reply, error);
111
112 /*
113 * To return to the mongoc_client_session_with_transaction() method, set
114 * *reply to a new copy of our local_reply before destroying it.
115 */
116 *reply = bson_copy (&local_reply);
117 bson_destroy (&local_reply);
118
119 bson_destroy (doc);
120 return retval;
121 }
122
123 int
124 main (int argc, char *argv[])
125 {
126 int exit_code = EXIT_FAILURE;
127
128 mongoc_uri_t *uri = NULL;
129 const char *uri_string = "mongodb://127.0.0.1/?appname=with-txn-cb-example";
130 mongoc_client_t *client = NULL;
131 mongoc_database_t *database = NULL;
132 mongoc_collection_t *collection = NULL;
133 mongoc_client_session_t *session = NULL;
134 bson_t *insert_opts = NULL;
135 bson_t reply;
136 ctx_t ctx;
137 char *str;
138 bson_error_t error;
139
140 /*
141 * Required to initialize libmongoc's internals
142 */
143 mongoc_init ();
144
145 /*
146 * Optionally get MongoDB URI from command line
147 */
148 if (argc > 1) {
149 uri_string = argv[1];
150 }
151
152 /*
153 * Safely create a MongoDB URI object from the given string
154 */
155 uri = mongoc_uri_new_with_error (uri_string, &error);
156 if (!uri) {
157 MONGOC_ERROR ("failed to parse URI: %s\n"
158 "error message: %s\n",
159 uri_string,
160 error.message);
161 goto done;
162 }
163
164 /*
165 * Create a new client instance
166 */
167 client = mongoc_client_new_from_uri (uri);
168 if (!client) {
169 goto done;
170 }
171
172 mongoc_client_set_error_api (client, 2);
173
174 /*
175 * Get a handle on the database "example-with-txn-cb"
176 */
177 database = mongoc_client_get_database (client, "example-with-txn-cb");
178
179 /*
180 * Inserting into a nonexistent collection normally creates it, but a
181 * collection can't be created in a transaction; create it now
182 */
183 collection =
184 mongoc_database_create_collection (database, "collection", NULL, &error);
185 if (!collection) {
186 /* code 48 is NamespaceExists, see error_codes.err in mongodb source */
187 if (error.code == 48) {
188 collection = mongoc_database_get_collection (database, "collection");
189 } else {
190 MONGOC_ERROR ("Failed to create collection: %s", error.message);
191 goto done;
192 }
193 }
194
195 /*
196 * Pass NULL for options - by default the session is causally consistent
197 */
198 session = mongoc_client_start_session (client, NULL, &error);
199 if (!session) {
200 MONGOC_ERROR ("Failed to start session: %s", error.message);
201 goto done;
202 }
203
204 /*
205 * Append a logical session id to command options
206 */
207 insert_opts = bson_new ();
208 if (!mongoc_client_session_append (session, insert_opts, &error)) {
209 MONGOC_ERROR ("Could not add session to opts: %s", error.message);
210 goto done;
211 }
212
213 ctx.collection = collection;
214 ctx.insert_opts = insert_opts;
215
216 /*
217 * This method will start a new transaction on session, run our callback
218 * function, i.e., &create_and_insert_doc, passing &ctx as an argument and
219 * commit the transaction.
220 */
221 if (!mongoc_client_session_with_transaction (
222 session, &create_and_insert_doc, NULL, &ctx, &reply, &error)) {
223 MONGOC_ERROR ("Insert failed: %s", error.message);
224 goto done;
225 }
226
227 str = bson_as_json (&reply, NULL);
228 printf ("%s\n", str);
229
230 exit_code = EXIT_SUCCESS;
231
232 done:
233 bson_free (str);
234 bson_destroy (&reply);
235 bson_destroy (insert_opts);
236 mongoc_client_session_destroy (session);
237 mongoc_collection_destroy (collection);
238 mongoc_database_destroy (database);
239 mongoc_client_destroy (client);
240 mongoc_uri_destroy (uri);
241
242 mongoc_cleanup ();
243
244 return exit_code;
245 }
246
247
248
250 MongoDB, Inc
251
253 2017-present, MongoDB, Inc
254
255
256
257
2581.17.6 Jun 0M3O,NG2O0C2_1CLIENT_SESSION_WITH_TRANSACTION(3)