|
34 | 34 |
|
35 | 35 |
|
36 | 36 | typedef void (*sample_command_fn_t) (mongoc_database_t *db);
|
| 37 | +typedef void (*sample_txn_command_fn_t) (mongoc_client_t *client); |
37 | 38 |
|
38 | 39 |
|
39 | 40 | static void
|
@@ -2543,7 +2544,6 @@ test_sample_change_stream_command (sample_command_fn_t fn,
|
2543 | 2544 | }
|
2544 | 2545 |
|
2545 | 2546 |
|
2546 |
| - |
2547 | 2547 | static void
|
2548 | 2548 | test_example_change_stream (mongoc_database_t *db)
|
2549 | 2549 | {
|
@@ -2980,6 +2980,149 @@ test_sample_indexes (mongoc_database_t *db)
|
2980 | 2980 | }
|
2981 | 2981 |
|
2982 | 2982 |
|
| 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 | + |
2983 | 3126 | static void
|
2984 | 3127 | test_sample_commands (void)
|
2985 | 3128 | {
|
@@ -3051,6 +3194,7 @@ test_sample_commands (void)
|
3051 | 3194 | test_sample_aggregation (db);
|
3052 | 3195 | test_sample_indexes (db);
|
3053 | 3196 | test_sample_run_command (db);
|
| 3197 | + test_sample_txn_command (test_example_txn_1, 1, client); |
3054 | 3198 |
|
3055 | 3199 | mongoc_collection_drop (collection, NULL);
|
3056 | 3200 |
|
|
0 commit comments