.\" Man page generated from reStructuredText. . . .nr rst2man-indent-level 0 . .de1 rstReportMargin \\$1 \\n[an-margin] level \\n[rst2man-indent-level] level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] - \\n[rst2man-indent0] \\n[rst2man-indent1] \\n[rst2man-indent2] .. .de1 INDENT .\" .rstReportMargin pre: . RS \\$1 . nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin] . nr rst2man-indent-level +1 .\" .rstReportMargin post: .. .de UNINDENT . RE .\" indent \\n[an-margin] .\" old: \\n[rst2man-indent\\n[rst2man-indent-level]] .nr rst2man-indent-level -1 .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] .in \\n[rst2man-indent\\n[rst2man-indent-level]]u .. .TH "MONGOC_CLIENT_SESSION_T" "3" "Feb 25, 2024" "1.26.0" "libmongoc" .sp Use a session for a sequence of operations, optionally with causal consistency. See \fI\%the MongoDB Manual Entry for Causal Consistency\fP\&. .SH SYNOPSIS .sp Start a session with \fI\%mongoc_client_start_session()\fP, use the session for a sequence of operations and multi\-document transactions, then free it with \fI\%mongoc_client_session_destroy()\fP\&. Any \fI\%mongoc_cursor_t\fP or \fI\%mongoc_change_stream_t\fP using a session must be destroyed before the session, and a session must be destroyed before the \fI\%mongoc_client_t\fP it came from. .sp By default, sessions are \fI\%causally consistent\fP\&. To disable causal consistency, before starting a session create a \fI\%mongoc_session_opt_t\fP with \fI\%mongoc_session_opts_new()\fP and call \fI\%mongoc_session_opts_set_causal_consistency()\fP, then free the struct with \fI\%mongoc_session_opts_destroy()\fP\&. .sp Unacknowledged writes are prohibited with sessions. .sp A \fI\%mongoc_client_session_t\fP must be used by only one thread at a time. Due to session pooling, \fI\%mongoc_client_start_session()\fP may return a session that has been idle for some time and is about to be closed after its idle timeout. Use the session within one minute of acquiring it to refresh the session and avoid a timeout. .SH FORK SAFETY .sp A \fI\%mongoc_client_session_t\fP is only usable in the parent process after a fork. The child process must call \fI\%mongoc_client_reset()\fP on the \fBclient\fP field. .SH EXAMPLE .sp example\-session.c .INDENT 0.0 .INDENT 3.5 .sp .EX /* gcc example\-session.c \-o example\-session \e * $(pkg\-config \-\-cflags \-\-libs libmongoc\-1.0) */ /* ./example\-session [CONNECTION_STRING] */ #include #include int main (int argc, char *argv[]) { int exit_code = EXIT_FAILURE; mongoc_client_t *client = NULL; const char *uri_string = \(dqmongodb://127.0.0.1/?appname=session\-example\(dq; mongoc_uri_t *uri = NULL; mongoc_client_session_t *client_session = NULL; mongoc_collection_t *collection = NULL; bson_error_t error; bson_t *selector = NULL; bson_t *update = NULL; bson_t *update_opts = NULL; bson_t *find_opts = NULL; mongoc_read_prefs_t *secondary = NULL; mongoc_cursor_t *cursor = NULL; const bson_t *doc; char *str; bool r; mongoc_init (); if (argc > 1) { uri_string = argv[1]; } uri = mongoc_uri_new_with_error (uri_string, &error); if (!uri) { fprintf (stderr, \(dqfailed to parse URI: %s\en\(dq \(dqerror message: %s\en\(dq, uri_string, error.message); goto done; } client = mongoc_client_new_from_uri (uri); if (!client) { goto done; } mongoc_client_set_error_api (client, 2); /* pass NULL for options \- by default the session is causally consistent */ client_session = mongoc_client_start_session (client, NULL, &error); if (!client_session) { fprintf (stderr, \(dqFailed to start session: %s\en\(dq, error.message); goto done; } collection = mongoc_client_get_collection (client, \(dqtest\(dq, \(dqcollection\(dq); selector = BCON_NEW (\(dq_id\(dq, BCON_INT32 (1)); update = BCON_NEW (\(dq$inc\(dq, \(dq{\(dq, \(dqx\(dq, BCON_INT32 (1), \(dq}\(dq); update_opts = bson_new (); if (!mongoc_client_session_append (client_session, update_opts, &error)) { fprintf (stderr, \(dqCould not add session to opts: %s\en\(dq, error.message); goto done; } r = mongoc_collection_update_one ( collection, selector, update, update_opts, NULL /* reply */, &error); if (!r) { fprintf (stderr, \(dqUpdate failed: %s\en\(dq, error.message); goto done; } bson_destroy (selector); selector = BCON_NEW (\(dq_id\(dq, BCON_INT32 (1)); secondary = mongoc_read_prefs_new (MONGOC_READ_SECONDARY); find_opts = BCON_NEW (\(dqmaxTimeMS\(dq, BCON_INT32 (2000)); if (!mongoc_client_session_append (client_session, find_opts, &error)) { fprintf (stderr, \(dqCould not add session to opts: %s\en\(dq, error.message); goto done; }; /* read from secondary. since we\(aqre in a causally consistent session, the * data is guaranteed to reflect the update we did on the primary. the query * blocks waiting for the secondary to catch up, if necessary, or times out * and fails after 2000 ms. */ cursor = mongoc_collection_find_with_opts ( collection, selector, find_opts, secondary); while (mongoc_cursor_next (cursor, &doc)) { str = bson_as_json (doc, NULL); fprintf (stdout, \(dq%s\en\(dq, str); bson_free (str); } if (mongoc_cursor_error (cursor, &error)) { fprintf (stderr, \(dqCursor Failure: %s\en\(dq, error.message); goto done; } exit_code = EXIT_SUCCESS; done: if (find_opts) { bson_destroy (find_opts); } if (update) { bson_destroy (update); } if (selector) { bson_destroy (selector); } if (update_opts) { bson_destroy (update_opts); } if (secondary) { mongoc_read_prefs_destroy (secondary); } /* destroy cursor, collection, session before the client they came from */ if (cursor) { mongoc_cursor_destroy (cursor); } if (collection) { mongoc_collection_destroy (collection); } if (client_session) { mongoc_client_session_destroy (client_session); } if (uri) { mongoc_uri_destroy (uri); } if (client) { mongoc_client_destroy (client); } mongoc_cleanup (); return exit_code; } .EE .UNINDENT .UNINDENT .SH AUTHOR MongoDB, Inc .SH COPYRIGHT 2017-present, MongoDB, Inc .\" Generated by docutils manpage writer. .