.\" 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_START_TRANSACTION" "3" "May 07, 2024" "1.27.1" "libmongoc" .SH SYNOPSIS .INDENT 0.0 .INDENT 3.5 .sp .EX bool mongoc_client_session_start_transaction (mongoc_client_session_t *session, const mongoc_transaction_opt_t *opts, bson_error_t *error); .EE .UNINDENT .UNINDENT .sp Start a multi\-document transaction for all following operations in this session. Any options provided in \fBopts\fP override options passed to \fI\%mongoc_session_opts_set_default_transaction_opts()\fP, and options inherited from the \fI\%mongoc_client_t\fP\&. The \fBopts\fP argument is copied and can be freed after calling this function. .sp The transaction must be completed with \fI\%mongoc_client_session_commit_transaction()\fP or \fI\%mongoc_client_session_abort_transaction()\fP\&. An in\-progress transaction is automatically aborted by \fI\%mongoc_client_session_destroy()\fP\&. .SH PARAMETERS .INDENT 0.0 .IP \(bu 2 \fBsession\fP: A \fI\%mongoc_client_session_t\fP\&. .IP \(bu 2 \fBopts\fP: A \fI\%mongoc_transaction_opt_t\fP or \fBNULL\fP\&. .IP \(bu 2 \fBerror\fP: An optional location for a \fI\%bson_error_t\fP or \fBNULL\fP\&. .UNINDENT .SH RETURN .sp Returns true if the transaction was started. Returns \fBfalse\fP and sets \fBerror\fP if there are invalid arguments, such as a session with a transaction already in progress. .SH EXAMPLE .sp The following example demonstrates how to use \fI\%error labels\fP to reliably execute a multi\-document transaction despite network errors and other transient failures. .sp example\-transaction.c .INDENT 0.0 .INDENT 3.5 .sp .EX /* gcc example\-transaction.c \-o example\-transaction \e * $(pkg\-config \-\-cflags \-\-libs libmongoc\-1.0) */ /* ./example\-transaction [CONNECTION_STRING] */ #include #include int main (int argc, char *argv[]) { int exit_code = EXIT_FAILURE; mongoc_client_t *client = NULL; mongoc_database_t *database = NULL; mongoc_collection_t *collection = NULL; mongoc_client_session_t *session = NULL; mongoc_session_opt_t *session_opts = NULL; mongoc_transaction_opt_t *default_txn_opts = NULL; mongoc_transaction_opt_t *txn_opts = NULL; mongoc_read_concern_t *read_concern = NULL; mongoc_write_concern_t *write_concern = NULL; const char *uri_string = \(dqmongodb://127.0.0.1/?appname=transaction\-example\(dq; mongoc_uri_t *uri; bson_error_t error; bson_t *doc = NULL; bson_t *insert_opts = NULL; int32_t i; int64_t start; bson_t reply = BSON_INITIALIZER; char *reply_json; bool r; mongoc_init (); if (argc > 1) { uri_string = argv[1]; } uri = mongoc_uri_new_with_error (uri_string, &error); if (!uri) { MONGOC_ERROR (\(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); database = mongoc_client_get_database (client, \(dqexample\-transaction\(dq); /* inserting into a nonexistent collection normally creates it, but a * collection can\(aqt be created in a transaction; create it now */ collection = mongoc_database_create_collection (database, \(dqcollection\(dq, NULL, &error); if (!collection) { /* code 48 is NamespaceExists, see error_codes.err in mongodb source */ if (error.code == 48) { collection = mongoc_database_get_collection (database, \(dqcollection\(dq); } else { MONGOC_ERROR (\(dqFailed to create collection: %s\(dq, error.message); goto done; } } /* a transaction\(aqs read preferences, read concern, and write concern can be * set on the client, on the default transaction options, or when starting * the transaction. for the sake of this example, set read concern on the * default transaction options. */ default_txn_opts = mongoc_transaction_opts_new (); read_concern = mongoc_read_concern_new (); mongoc_read_concern_set_level (read_concern, \(dqsnapshot\(dq); mongoc_transaction_opts_set_read_concern (default_txn_opts, read_concern); session_opts = mongoc_session_opts_new (); mongoc_session_opts_set_default_transaction_opts (session_opts, default_txn_opts); session = mongoc_client_start_session (client, session_opts, &error); if (!session) { MONGOC_ERROR (\(dqFailed to start session: %s\(dq, error.message); goto done; } /* in this example, set write concern when starting the transaction */ txn_opts = mongoc_transaction_opts_new (); write_concern = mongoc_write_concern_new (); mongoc_write_concern_set_wmajority (write_concern, 1000 /* wtimeout */); mongoc_transaction_opts_set_write_concern (txn_opts, write_concern); insert_opts = bson_new (); if (!mongoc_client_session_append (session, insert_opts, &error)) { MONGOC_ERROR (\(dqCould not add session to opts: %s\(dq, error.message); goto done; } retry_transaction: r = mongoc_client_session_start_transaction (session, txn_opts, &error); if (!r) { MONGOC_ERROR (\(dqFailed to start transaction: %s\(dq, error.message); goto done; } /* insert two documents \- on error, retry the whole transaction */ for (i = 0; i < 2; i++) { doc = BCON_NEW (\(dq_id\(dq, BCON_INT32 (i)); bson_destroy (&reply); r = mongoc_collection_insert_one (collection, doc, insert_opts, &reply, &error); bson_destroy (doc); if (!r) { MONGOC_ERROR (\(dqInsert failed: %s\(dq, error.message); mongoc_client_session_abort_transaction (session, NULL); /* a network error, primary failover, or other temporary error in a * transaction includes {\(dqerrorLabels\(dq: [\(dqTransientTransactionError\(dq]}, * meaning that trying the entire transaction again may succeed */ if (mongoc_error_has_label (&reply, \(dqTransientTransactionError\(dq)) { goto retry_transaction; } goto done; } reply_json = bson_as_json (&reply, NULL); printf (\(dq%s\en\(dq, reply_json); bson_free (reply_json); } /* in case of transient errors, retry for 5 seconds to commit transaction */ start = bson_get_monotonic_time (); while (bson_get_monotonic_time () \- start < 5 * 1000 * 1000) { bson_destroy (&reply); r = mongoc_client_session_commit_transaction (session, &reply, &error); if (r) { /* success */ break; } else { MONGOC_ERROR (\(dqWarning: commit failed: %s\(dq, error.message); if (mongoc_error_has_label (&reply, \(dqTransientTransactionError\(dq)) { goto retry_transaction; } else if (mongoc_error_has_label (&reply, \(dqUnknownTransactionCommitResult\(dq)) { /* try again to commit */ continue; } /* unrecoverable error trying to commit */ break; } } exit_code = EXIT_SUCCESS; done: bson_destroy (&reply); bson_destroy (insert_opts); mongoc_write_concern_destroy (write_concern); mongoc_read_concern_destroy (read_concern); mongoc_transaction_opts_destroy (txn_opts); mongoc_transaction_opts_destroy (default_txn_opts); mongoc_client_session_destroy (session); mongoc_collection_destroy (collection); mongoc_database_destroy (database); mongoc_uri_destroy (uri); 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. .