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
40 below.
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
57 reply.
58
60 Use with_transaction() to run a callback within a transaction.INDENT
61 0.0
62
63 /* gcc example-with-transaction-cb.c -o example-with-transaction-cb $(pkg-config
64 * --cflags --libs libmongoc-1.0) */
65
66 /* ./example-with-transaction-cb [CONNECTION_STRING] */
67
68 #include <mongoc/mongoc.h>
69 #include <stdio.h>
70 #include <stdlib.h>
71
72 /*
73 * We pass this context object to mongoc_client_session_with_transaction() along
74 * with our callback function. The context object will be passed to our callback
75 * function when it runs, so we can access it.
76 */
77 typedef struct {
78 mongoc_collection_t *collection;
79 bson_t *insert_opts;
80 } ctx_t;
81
82 /*
83 * We pass this method as the callback to
84 * mongoc_client_session_with_transaction(). The insert that this method
85 * performs will happen inside of a new transaction.
86 */
87 bool
88 create_and_insert_doc (mongoc_client_session_t *session,
89 void *ctx,
90 bson_t **reply, /* out param for our server reply */
91 bson_error_t *error)
92 {
93 /*
94 * mongoc_collection_insert_one requires an uninitialized, stack-allocated
95 * bson_t to receive the update result
96 */
97 bson_t local_reply;
98 bson_t *doc = NULL;
99 ctx_t *data = NULL;
100 bool retval;
101
102 /*
103 * Create a new bson document - { id: 1 }
104 */
105 doc = BCON_NEW ("_id", BCON_INT32 (1));
106
107 printf (
108 "Running the user-defined callback in a newly created transaction...\n");
109 data = (ctx_t *) ctx;
110 retval = mongoc_collection_insert_one (
111 data->collection, doc, data->insert_opts, &local_reply, error);
112
113 /*
114 * To return to the mongoc_client_session_with_transaction() method, set
115 * *reply to a new copy of our local_reply before destroying it.
116 */
117 *reply = bson_copy (&local_reply);
118 bson_destroy (&local_reply);
119
120 bson_destroy (doc);
121 return retval;
122 }
123
124 int
125 main (int argc, char *argv[])
126 {
127 int exit_code = EXIT_FAILURE;
128
129 mongoc_uri_t *uri = NULL;
130 const char *uri_string = "mongodb://127.0.0.1/?appname=with-txn-cb-example";
131 mongoc_client_t *client = NULL;
132 mongoc_database_t *database = NULL;
133 mongoc_collection_t *collection = NULL;
134 mongoc_client_session_t *session = NULL;
135 bson_t *insert_opts = NULL;
136 bson_t reply;
137 ctx_t ctx;
138 char *str;
139 bson_error_t error;
140
141 /*
142 * Required to initialize libmongoc's internals
143 */
144 mongoc_init ();
145
146 /*
147 * Optionally get MongoDB URI from command line
148 */
149 if (argc > 1) {
150 uri_string = argv[1];
151 }
152
153 /*
154 * Safely create a MongoDB URI object from the given string
155 */
156 uri = mongoc_uri_new_with_error (uri_string, &error);
157 if (!uri) {
158 MONGOC_ERROR ("failed to parse URI: %s\n"
159 "error message: %s\n",
160 uri_string,
161 error.message);
162 goto done;
163 }
164
165 /*
166 * Create a new client instance
167 */
168 client = mongoc_client_new_from_uri (uri);
169 if (!client) {
170 goto done;
171 }
172
173 mongoc_client_set_error_api (client, 2);
174
175 /*
176 * Get a handle on the database "example-with-txn-cb"
177 */
178 database = mongoc_client_get_database (client, "example-with-txn-cb");
179
180 /*
181 * Inserting into a nonexistent collection normally creates it, but a
182 * collection can't be created in a transaction; create it now
183 */
184 collection =
185 mongoc_database_create_collection (database, "collection", NULL, &error);
186 if (!collection) {
187 /* code 48 is NamespaceExists, see error_codes.err in mongodb source */
188 if (error.code == 48) {
189 collection = mongoc_database_get_collection (database, "collection");
190 } else {
191 MONGOC_ERROR ("Failed to create collection: %s", error.message);
192 goto done;
193 }
194 }
195
196 /*
197 * Pass NULL for options - by default the session is causally consistent
198 */
199 session = mongoc_client_start_session (client, NULL, &error);
200 if (!session) {
201 MONGOC_ERROR ("Failed to start session: %s", error.message);
202 goto done;
203 }
204
205 /*
206 * Append a logical session id to command options
207 */
208 insert_opts = bson_new ();
209 if (!mongoc_client_session_append (session, insert_opts, &error)) {
210 MONGOC_ERROR ("Could not add session to opts: %s", error.message);
211 goto done;
212 }
213
214 ctx.collection = collection;
215 ctx.insert_opts = insert_opts;
216
217 /*
218 * This method will start a new transaction on session, run our callback
219 * function, i.e., &create_and_insert_doc, passing &ctx as an argument and
220 * commit the transaction.
221 */
222 if (!mongoc_client_session_with_transaction (
223 session, &create_and_insert_doc, NULL, &ctx, &reply, &error)) {
224 MONGOC_ERROR ("Insert failed: %s", error.message);
225 goto done;
226 }
227
228 str = bson_as_json (&reply, NULL);
229 printf ("%s\n", str);
230
231 exit_code = EXIT_SUCCESS;
232
233 done:
234 bson_free (str);
235 bson_destroy (&reply);
236 bson_destroy (insert_opts);
237 mongoc_client_session_destroy (session);
238 mongoc_collection_destroy (collection);
239 mongoc_database_destroy (database);
240 mongoc_client_destroy (client);
241 mongoc_uri_destroy (uri);
242
243 mongoc_cleanup ();
244
245 return exit_code;
246 }
247
248
249
251 MongoDB, Inc
252
254 2017-present, MongoDB, Inc
255
256
257
258
2591.16.2 Feb 2M5O,NG2O0C2_0CLIENT_SESSION_WITH_TRANSACTION(3)