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