1MONGOC_CLIENT_SESSION_T(3) libmongoc MONGOC_CLIENT_SESSION_T(3)
2
3
4
5Use a session for a sequence of operations, optionally with causal consis‐
6tency. See the MongoDB Manual Entry for Causal Consistency.
7
9 Start a session with mongoc_client_start_session(), use the session for
10 a sequence of operations and multi-document transactions, then free it
11 with mongoc_client_session_destroy(). Any mongoc_cursor_t or
12 mongoc_change_stream_t using a session must be destroyed before the
13 session, and a session must be destroyed before the mongoc_client_t it
14 came from.
15
16 By default, sessions are causally consistent. To disable causal consis‐
17 tency, before starting a session create a mongoc_session_opt_t with
18 mongoc_session_opts_new() and call
19 mongoc_session_opts_set_causal_consistency(), then free the struct with
20 mongoc_session_opts_destroy().
21
22 Unacknowledged writes are prohibited with sessions.
23
24 A mongoc_client_session_t must be used by only one thread at a time.
25 Due to session pooling, mongoc_client_start_session() may return a ses‐
26 sion that has been idle for some time and is about to be closed after
27 its idle timeout. Use the session within one minute of acquiring it to
28 refresh the session and avoid a timeout.
29
31 A mongoc_client_session_t is only usable in the parent process after a
32 fork. The child process must call mongoc_client_reset() on the client
33 field.
34
36 example-session.c
37
38 /* gcc example-session.c -o example-session \
39 * $(pkg-config --cflags --libs libmongoc-1.0) */
40
41 /* ./example-session [CONNECTION_STRING] */
42
43 #include <stdio.h>
44 #include <mongoc/mongoc.h>
45
46
47 int
48 main (int argc, char *argv[])
49 {
50 int exit_code = EXIT_FAILURE;
51
52 mongoc_client_t *client = NULL;
53 const char *uri_string = "mongodb://127.0.0.1/?appname=session-example";
54 mongoc_uri_t *uri = NULL;
55 mongoc_client_session_t *client_session = NULL;
56 mongoc_collection_t *collection = NULL;
57 bson_error_t error;
58 bson_t *selector = NULL;
59 bson_t *update = NULL;
60 bson_t *update_opts = NULL;
61 bson_t *find_opts = NULL;
62 mongoc_read_prefs_t *secondary = NULL;
63 mongoc_cursor_t *cursor = NULL;
64 const bson_t *doc;
65 char *str;
66 bool r;
67
68 mongoc_init ();
69
70 if (argc > 1) {
71 uri_string = argv[1];
72 }
73
74 uri = mongoc_uri_new_with_error (uri_string, &error);
75 if (!uri) {
76 fprintf (stderr,
77 "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
91 /* pass NULL for options - by default the session is causally consistent */
92 client_session = mongoc_client_start_session (client, NULL, &error);
93 if (!client_session) {
94 fprintf (stderr, "Failed to start session: %s\n", error.message);
95 goto done;
96 }
97
98 collection = mongoc_client_get_collection (client, "test", "collection");
99 selector = BCON_NEW ("_id", BCON_INT32 (1));
100 update = BCON_NEW ("$inc", "{", "x", BCON_INT32 (1), "}");
101 update_opts = bson_new ();
102 if (!mongoc_client_session_append (client_session, update_opts, &error)) {
103 fprintf (stderr, "Could not add session to opts: %s\n", error.message);
104 goto done;
105 }
106
107 r = mongoc_collection_update_one (
108 collection, selector, update, update_opts, NULL /* reply */, &error);
109
110 if (!r) {
111 fprintf (stderr, "Update failed: %s\n", error.message);
112 goto done;
113 }
114
115 bson_destroy (selector);
116 selector = BCON_NEW ("_id", BCON_INT32 (1));
117 secondary = mongoc_read_prefs_new (MONGOC_READ_SECONDARY);
118
119 find_opts = BCON_NEW ("maxTimeMS", BCON_INT32 (2000));
120 if (!mongoc_client_session_append (client_session, find_opts, &error)) {
121 fprintf (stderr, "Could not add session to opts: %s\n", error.message);
122 goto done;
123 };
124
125 /* read from secondary. since we're in a causally consistent session, the
126 * data is guaranteed to reflect the update we did on the primary. the query
127 * blocks waiting for the secondary to catch up, if necessary, or times out
128 * and fails after 2000 ms.
129 */
130 cursor = mongoc_collection_find_with_opts (
131 collection, selector, find_opts, secondary);
132
133 while (mongoc_cursor_next (cursor, &doc)) {
134 str = bson_as_json (doc, NULL);
135 fprintf (stdout, "%s\n", str);
136 bson_free (str);
137 }
138
139 if (mongoc_cursor_error (cursor, &error)) {
140 fprintf (stderr, "Cursor Failure: %s\n", error.message);
141 goto done;
142 }
143
144 exit_code = EXIT_SUCCESS;
145
146 done:
147 if (find_opts) {
148 bson_destroy (find_opts);
149 }
150 if (update) {
151 bson_destroy (update);
152 }
153 if (selector) {
154 bson_destroy (selector);
155 }
156 if (update_opts) {
157 bson_destroy (update_opts);
158 }
159 if (secondary) {
160 mongoc_read_prefs_destroy (secondary);
161 }
162 /* destroy cursor, collection, session before the client they came from */
163 if (cursor) {
164 mongoc_cursor_destroy (cursor);
165 }
166 if (collection) {
167 mongoc_collection_destroy (collection);
168 }
169 if (client_session) {
170 mongoc_client_session_destroy (client_session);
171 }
172 if (uri) {
173 mongoc_uri_destroy (uri);
174 }
175 if (client) {
176 mongoc_client_destroy (client);
177 }
178
179 mongoc_cleanup ();
180
181 return exit_code;
182 }
183
184
186 MongoDB, Inc
187
189 2017-present, MongoDB, Inc
190
191
192
193
1941.25.1 Nov 08, 2023 MONGOC_CLIENT_SESSION_T(3)