Skip to content

Commit 01e2a84

Browse files
committed
CDRIVER-2663 txn example for MongoDB Manual
1 parent c957a99 commit 01e2a84

File tree

4 files changed

+163
-8
lines changed

4 files changed

+163
-8
lines changed

src/libmongoc/tests/test-libmongoc.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1942,6 +1942,21 @@ test_framework_skip_if_no_uds (void)
19421942
}
19431943

19441944

1945+
int
1946+
test_framework_skip_if_no_txns (void)
1947+
{
1948+
if (test_framework_skip_if_no_crypto () &&
1949+
test_framework_skip_if_no_sessions () &&
1950+
test_framework_skip_if_not_replset () &&
1951+
test_framework_skip_if_max_wire_version_less_than_7 ()) {
1952+
return 1;
1953+
}
1954+
1955+
/* transactions not supported, skip the test */
1956+
return 0;
1957+
}
1958+
1959+
19451960
bool
19461961
test_framework_max_wire_version_at_least (int version)
19471962
{

src/libmongoc/tests/test-libmongoc.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,8 @@ test_framework_skip_if_windows (void);
138138
int
139139
test_framework_skip_if_no_uds (void); /* skip if no Unix domain socket */
140140
int
141+
test_framework_skip_if_no_txns (void);
142+
int
141143
test_framework_skip_if_not_mongos (void);
142144
int
143145
test_framework_skip_if_not_replset (void);

src/libmongoc/tests/test-mongoc-sample-commands.c

Lines changed: 145 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434

3535

3636
typedef void (*sample_command_fn_t) (mongoc_database_t *db);
37+
typedef void (*sample_txn_command_fn_t) (mongoc_client_t *client);
3738

3839

3940
static void
@@ -2543,7 +2544,6 @@ test_sample_change_stream_command (sample_command_fn_t fn,
25432544
}
25442545

25452546

2546-
25472547
static void
25482548
test_example_change_stream (mongoc_database_t *db)
25492549
{
@@ -2980,6 +2980,149 @@ test_sample_indexes (mongoc_database_t *db)
29802980
}
29812981

29822982

2983+
static void
2984+
test_sample_txn_command (sample_txn_command_fn_t fn,
2985+
int exampleno,
2986+
mongoc_client_t *client)
2987+
{
2988+
char *example_name;
2989+
mongoc_collection_t *tmp_collection;
2990+
bson_error_t error;
2991+
bool r;
2992+
2993+
if (!test_framework_skip_if_no_txns ()) {
2994+
return;
2995+
}
2996+
2997+
example_name = bson_strdup_printf ("example %d", exampleno);
2998+
capture_logs (true);
2999+
3000+
/* preliminary: create collections outside txn */
3001+
tmp_collection = mongoc_client_get_collection (client, "hr", "employees");
3002+
mongoc_collection_drop (tmp_collection, NULL);
3003+
r = mongoc_collection_insert_one (
3004+
tmp_collection,
3005+
tmp_bson ("{'employee': 3, 'status': 'Active'}"),
3006+
NULL,
3007+
NULL,
3008+
&error);
3009+
ASSERT_OR_PRINT (r, error);
3010+
mongoc_collection_destroy (tmp_collection);
3011+
3012+
tmp_collection = mongoc_client_get_collection (
3013+
client, "reporting", "events");
3014+
mongoc_collection_drop (tmp_collection, NULL);
3015+
r = mongoc_collection_insert_one (
3016+
tmp_collection,
3017+
tmp_bson ("{'employee': 3, 'status': {'new': 'Active', 'old': null}}"),
3018+
NULL,
3019+
NULL,
3020+
&error);
3021+
ASSERT_OR_PRINT (r, error);
3022+
mongoc_collection_destroy (tmp_collection);
3023+
3024+
fn (client);
3025+
3026+
ASSERT_NO_CAPTURED_LOGS (example_name);
3027+
3028+
bson_free (example_name);
3029+
}
3030+
3031+
3032+
static void
3033+
test_example_txn_1 (mongoc_client_t *client)
3034+
{
3035+
/* Start Transactions Intro Example 1 */
3036+
mongoc_collection_t *employees;
3037+
mongoc_collection_t *events;
3038+
mongoc_client_session_t *session;
3039+
mongoc_read_concern_t *rc;
3040+
mongoc_write_concern_t *wc;
3041+
mongoc_transaction_opt_t *txn_opts;
3042+
bson_t opts = BSON_INITIALIZER;
3043+
bson_t *filter;
3044+
bson_t *update;
3045+
bson_t *event;
3046+
bson_t reply;
3047+
bson_error_t error;
3048+
bool r;
3049+
3050+
employees = mongoc_client_get_collection (client, "hr", "employees");
3051+
events = mongoc_client_get_collection (client, "reporting", "events");
3052+
session = mongoc_client_start_session (client, NULL, &error);
3053+
if (!session) {
3054+
MONGOC_ERROR ("%s", error.message);
3055+
}
3056+
3057+
rc = mongoc_read_concern_new ();
3058+
mongoc_read_concern_set_level (rc, MONGOC_READ_CONCERN_LEVEL_SNAPSHOT);
3059+
wc = mongoc_write_concern_new ();
3060+
mongoc_write_concern_set_w (wc, MONGOC_WRITE_CONCERN_W_MAJORITY);
3061+
txn_opts = mongoc_transaction_opts_new ();
3062+
mongoc_transaction_opts_set_read_concern (txn_opts, rc);
3063+
mongoc_transaction_opts_set_write_concern (txn_opts, wc);
3064+
3065+
r = mongoc_client_session_start_transaction (session, txn_opts, &error);
3066+
if (!r) {
3067+
MONGOC_ERROR ("%s", error.message);
3068+
}
3069+
3070+
r = mongoc_client_session_append (session, &opts, &error);
3071+
if (!r) {
3072+
MONGOC_ERROR ("%s", error.message);
3073+
}
3074+
3075+
filter = BCON_NEW ("employee", BCON_INT32 (3));
3076+
update = BCON_NEW ("$set", "{", "status", "Inactive", "}");
3077+
r = mongoc_collection_update_one (
3078+
employees, filter, update, &opts, &reply, &error);
3079+
3080+
if (!r) {
3081+
MONGOC_ERROR ("%s", error.message);
3082+
}
3083+
3084+
bson_destroy (&reply);
3085+
3086+
event = BCON_NEW ("employee", BCON_INT32 (3));
3087+
BCON_APPEND (event, "status", "{", "new", "Inactive", "old", "Active", "}");
3088+
3089+
r = mongoc_collection_insert_one (events, event, &opts, &reply, &error);
3090+
if (!r) {
3091+
MONGOC_ERROR ("%s", error.message);
3092+
}
3093+
3094+
while (true) {
3095+
bson_destroy (&reply);
3096+
3097+
r = mongoc_client_session_commit_transaction (session, &reply, &error);
3098+
if (r) {
3099+
MONGOC_INFO ("Transaction committed.");
3100+
break;
3101+
} else if (
3102+
mongoc_error_has_label (&reply, "UnknownTransactionCommitResult")) {
3103+
MONGOC_INFO (
3104+
"UnknownTransactionCommitResult, retrying commit operation ...");
3105+
} else {
3106+
MONGOC_ERROR ("Error during commit: %s", error.message);
3107+
break;
3108+
}
3109+
}
3110+
3111+
mongoc_collection_destroy (employees);
3112+
mongoc_collection_destroy (events);
3113+
mongoc_client_session_destroy (session);
3114+
mongoc_read_concern_destroy (rc);
3115+
mongoc_write_concern_destroy (wc);
3116+
mongoc_transaction_opts_destroy (txn_opts);
3117+
bson_destroy (&opts);
3118+
bson_destroy (filter);
3119+
bson_destroy (update);
3120+
bson_destroy (event);
3121+
bson_destroy (&reply);
3122+
/* End Transactions Intro Example 1 */
3123+
}
3124+
3125+
29833126
static void
29843127
test_sample_commands (void)
29853128
{
@@ -3051,6 +3194,7 @@ test_sample_commands (void)
30513194
test_sample_aggregation (db);
30523195
test_sample_indexes (db);
30533196
test_sample_run_command (db);
3197+
test_sample_txn_command (test_example_txn_1, 1, client);
30543198

30553199
mongoc_collection_drop (collection, NULL);
30563200

src/libmongoc/tests/test-mongoc-transactions.c

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -115,13 +115,7 @@ test_transactions_install (TestSuite *suite)
115115

116116
ASSERT (realpath (JSON_DIR "/transactions", resolved));
117117
install_json_test_suite_with_check (
118-
suite,
119-
resolved,
120-
test_transactions_cb,
121-
test_framework_skip_if_no_crypto,
122-
test_framework_skip_if_no_sessions,
123-
test_framework_skip_if_not_replset,
124-
test_framework_skip_if_max_wire_version_less_than_7);
118+
suite, resolved, test_transactions_cb, test_framework_skip_if_no_txns);
125119

126120
/* skip mongos for now - txn support coming in 4.1.0 */
127121
TestSuite_AddFull (suite,

0 commit comments

Comments
 (0)