ํธ๋์ญ์
์ด ํ์ด์ง์ ๋ด์ฉ
MongoDB์์ ๋จ์ผ ๋ฌธ์์ ๋ํ ์์ ์ ์์์ ์ผ๋ก ์ด๋ฃจ์ด์ง๋๋ค. ์๋ฒ ๋๋ ๋ฌธ์์ ๋ฐฐ์ด์ ์ฌ์ฉํ๋ฉด ์ฌ๋ฌ ๋ฌธ์์ ์ปฌ๋ ์ ์ ๊ฑธ์ณ ์ ๊ทํํ๋ ๋์ ๋จ์ผ ๋ฌธ์ ๊ตฌ์กฐ์์ ๋ฐ์ดํฐ ๊ฐ์ ๊ด๊ณ๋ฅผ ์บก์ฒํ ์ ์์ผ๋ฏ๋ก ์ด๋ฌํ ๋จ์ผ ๋ฌธ์ ์์์ฑ์ ๋ง์ ์ค์ ์ฌ์ฉ ์ฌ๋ก์์ ๋ถ์ฐ ํธ๋์ญ์ ์ ํ์์ฑ์ ์์ ์ค๋๋ค.
์ฌ๋ฌ ๋ฌธ์ (๋จ์ผ ๋๋ ์ฌ๋ฌ ์ปฌ๋ ์ )์ ๋ํ ์ฝ๊ธฐ ๋ฐ ์ฐ๊ธฐ์ ์์์ฑ์ด ํ์ํ ์ํฉ์ ๊ฒฝ์ฐ, MongoDB๋ ๋ถ์ฐ ํธ๋์ญ์ ์ ์ง์ํฉ๋๋ค. ๋ถ์ฐ ํธ๋์ญ์ ์ ์ฌ์ฉํ๋ฉด ์ฌ๋ฌ ์์ , ์ปฌ๋ ์ , ๋ฐ์ดํฐ๋ฒ ์ด์ค, ๋ฌธ์ ๋ฐ ์ค๋์์ ํธ๋์ญ์ ์ ์ฌ์ฉํ ์ ์์ต๋๋ค.
์ด ํ์ด์ง์ ์ ๋ณด๋ ๋ค์ ํ๊ฒฝ์์ ํธ์คํ ๋๋ ๋ฐฐํฌ์ ์ ์ฉ๋ฉ๋๋ค.
MongoDB Atlas: ํด๋ผ์ฐ๋์์์ MongoDB ๋ฐฐํฌ๋ฅผ ์ํ ์์ ๊ด๋ฆฌํ ์๋น์ค
MongoDB Enterprise: MongoDB์ ๊ตฌ๋ ๊ธฐ๋ฐ ์์ฒด ๊ด๋ฆฌ ๋ฒ์
MongoDB Community: MongoDB์ ์์ค ์ฌ์ฉ ๊ฐ๋ฅ ๋ฌด๋ฃ ์์ฒด ๊ด๋ฆฌ ๋ฒ์
ํธ๋์ญ์ API
โค ์ค๋ฅธ์ชฝ ์์ ์๋ ์ธ์ด ์ ํ ๋๋กญ๋ค์ด ๋ฉ๋ด๋ฅผ ์ฌ์ฉํ์ฌ ๋ค์ ์์์ ์ธ์ด๋ฅผ ์ค์ ํ์ธ์.
์ด ์์์๋ ํธ๋์ญ์ API์ ์ฃผ์ ๊ตฌ์ฑ์์๋ฅผ ๊ฐ์กฐํฉ๋๋ค. ํนํ ์ฝ๋ฐฑ API๋ฅผ ์ฌ์ฉํฉ๋๋ค. ์ฝ๋ฐฑ API:
ํธ๋์ญ์ ์ ์์ํฉ๋๋ค.
์ง์ ๋ ์์ ์ ์คํํฉ๋๋ค.
๊ฒฐ๊ณผ๋ฅผ ์ปค๋ฐํ๊ฑฐ๋ ์ค๋ฅ๊ฐ ๋ฐ์ํ์ฌ ํธ๋์ญ์ ์ ์ข ๋ฃํฉ๋๋ค.
DuplicateKeyError
์ ๊ฐ์ ์๋ฒ ์ธก ์์
์ ์ค๋ฅ๋ก ์ธํด ํธ๋์ญ์
์ด ์ข
๋ฃ๋๊ณ ์ฌ์ฉ์์๊ฒ ํธ๋์ญ์
์ด ์ข
๋ฃ๋์์์ ์๋ฆฌ๋ ๋ช
๋ น ์ค๋ฅ๊ฐ ๋ฐ์ํ ์ ์์ต๋๋ค. ์ด ๋์์ ์์๋ ๊ฒ์ด๋ฉฐ ํด๋ผ์ด์ธํธ๊ฐ Session.abortTransaction()
๋ฅผ ํธ์ถํ์ง ์์ ๊ฒฝ์ฐ์๋ ๋ฐ์ํฉ๋๋ค. ์ฌ์ฉ์ ์ง์ ์ค๋ฅ ์ฒ๋ฆฌ๋ฅผ ํตํฉํ๋ ค๋ฉด ํธ๋์ญ์
์์ Core API๋ฅผ ์ฌ์ฉํ์ธ์.
์ฝ๋ฐฑ Callback API API ๋ ํน์ ์ค๋ฅ์ ๋ํ ์ฌ์๋ ๋ก์ง์ ํตํฉํฉ๋๋ค. ์ด์ ์ ๋ TransientTransactionError ๋๋ UnknownTransactionCommitResult ์ปค๋ฐ ์ค๋ฅ ํ์ ํธ๋์ญ์ ์ ๋ค์ ์คํํ๋ ค๊ณ ์๋ํฉ๋๋ค.
MongoDB 6.2๋ถํฐ ์๋ฒ๋ TransactionTooLargeForCache ์ค๋ฅ๋ฅผ ์์ ํ๋ ๊ฒฝ์ฐ ํธ๋์ญ์ ์ ์ฌ์๋ํ์ง ์์ต๋๋ค.
์ค์
MongoDB ๋ฒ์ ์ ๋ง๋ MongoDB ๋๋ผ์ด๋ฒ๋ฅผ ์ฌ์ฉํ์ธ์.
๋๋ผ์ด๋ฒ๋ฅผ ์ฌ์ฉํ ๋ ํธ๋์ญ์ ์ ๊ฐ ์์ ์ ๊ฐ ์์ ์ ์ธ์ ์ ์ ๋ฌํด์ผ ํฉ๋๋ค.
ํธ๋์ญ์ ์ ์์ ์ ํธ๋์ญ์ ์์ค์ ์ฝ๊ธฐ ๊ณ ๋ ค, ํธ๋์ญ์ ์์ค์ ์ฐ๊ธฐ ๊ณ ๋ ค, ํธ๋์ญ์ ์์ค์ ์ฝ๊ธฐ ์ค์ ์ ์ฌ์ฉํฉ๋๋ค.
ํธ๋์ญ์ ์์ ์์์ ๋๋ ๋ช ์์ ์ผ๋ก ์ปฌ๋ ์ ์ ๋ง๋ค ์ ์์ต๋๋ค. ํธ๋์ญ์ ์์ ์ปฌ๋ ์ ๋ฐ ์ธ๋ฑ์ค ์์ฑ์ ์ฐธ์กฐํ์ธ์.
static bool with_transaction_example (bson_error_t *error) { mongoc_client_t *client = NULL; mongoc_write_concern_t *wc = NULL; mongoc_collection_t *coll = NULL; bool success = false; bool ret = false; bson_t *doc = NULL; bson_t *insert_opts = NULL; mongoc_client_session_t *session = NULL; mongoc_transaction_opt_t *txn_opts = NULL; /* For a replica set, include the replica set name and a seedlist of the * members in the URI string; e.g. * uri_repl = "mongodb://mongodb0.example.com:27017,mongodb1.example.com:" \ * "27017/?replicaSet=myRepl"; * client = mongoc_client_new (uri_repl); * For a sharded cluster, connect to the mongos instances; e.g. * uri_sharded = * "mongodb://mongos0.example.com:27017,mongos1.example.com:27017/"; * client = mongoc_client_new (uri_sharded); */ client = get_client (); /* Prereq: Create collections. Note Atlas connection strings include a majority write * concern by default. */ wc = mongoc_write_concern_new (); mongoc_write_concern_set_wmajority (wc, 0); insert_opts = bson_new (); mongoc_write_concern_append (wc, insert_opts); coll = mongoc_client_get_collection (client, "mydb1", "foo"); doc = BCON_NEW ("abc", BCON_INT32 (0)); ret = mongoc_collection_insert_one (coll, doc, insert_opts, NULL /* reply */, error); if (!ret) { goto fail; } bson_destroy (doc); mongoc_collection_destroy (coll); coll = mongoc_client_get_collection (client, "mydb2", "bar"); doc = BCON_NEW ("xyz", BCON_INT32 (0)); ret = mongoc_collection_insert_one (coll, doc, insert_opts, NULL /* reply */, error); if (!ret) { goto fail; } /* Step 1: Start a client session. */ session = mongoc_client_start_session (client, NULL /* opts */, error); if (!session) { goto fail; } /* Step 2: Optional. Define options to use for the transaction. */ txn_opts = mongoc_transaction_opts_new (); mongoc_transaction_opts_set_write_concern (txn_opts, wc); /* Step 3: Use mongoc_client_session_with_transaction to start a transaction, * execute the callback, and commit (or abort on error). */ ret = mongoc_client_session_with_transaction (session, callback, txn_opts, NULL /* ctx */, NULL /* reply */, error); if (!ret) { goto fail; } success = true; fail: bson_destroy (doc); mongoc_collection_destroy (coll); bson_destroy (insert_opts); mongoc_write_concern_destroy (wc); mongoc_transaction_opts_destroy (txn_opts); mongoc_client_session_destroy (session); mongoc_client_destroy (client); return success; } /* Define the callback that specifies the sequence of operations to perform * inside the transactions. */ static bool callback (mongoc_client_session_t *session, void *ctx, bson_t **reply, bson_error_t *error) { mongoc_client_t *client = NULL; mongoc_collection_t *coll = NULL; bson_t *doc = NULL; bool success = false; bool ret = false; BSON_UNUSED (ctx); client = mongoc_client_session_get_client (session); coll = mongoc_client_get_collection (client, "mydb1", "foo"); doc = BCON_NEW ("abc", BCON_INT32 (1)); ret = mongoc_collection_insert_one (coll, doc, NULL /* opts */, *reply, error); if (!ret) { goto fail; } bson_destroy (doc); mongoc_collection_destroy (coll); coll = mongoc_client_get_collection (client, "mydb2", "bar"); doc = BCON_NEW ("xyz", BCON_INT32 (999)); ret = mongoc_collection_insert_one (coll, doc, NULL /* opts */, *reply, error); if (!ret) { goto fail; } success = true; fail: mongoc_collection_destroy (coll); bson_destroy (doc); return success; }
์ด ์์์๋ ํธ๋์ญ์ API์ ์ฃผ์ ๊ตฌ์ฑ์์๋ฅผ ๊ฐ์กฐํฉ๋๋ค. ํนํ ์ฝ๋ฐฑ API๋ฅผ ์ฌ์ฉํฉ๋๋ค. ์ฝ๋ฐฑ API:
ํธ๋์ญ์ ์ ์์ํฉ๋๋ค.
์ง์ ๋ ์์ ์ ์คํํฉ๋๋ค.
๊ฒฐ๊ณผ๋ฅผ ์ปค๋ฐํ๊ฑฐ๋ ์ค๋ฅ๊ฐ ๋ฐ์ํ์ฌ ํธ๋์ญ์ ์ ์ข ๋ฃํฉ๋๋ค.
DuplicateKeyError
์ ๊ฐ์ ์๋ฒ ์ธก ์์
์ ์ค๋ฅ๋ก ์ธํด ํธ๋์ญ์
์ด ์ข
๋ฃ๋๊ณ ์ฌ์ฉ์์๊ฒ ํธ๋์ญ์
์ด ์ข
๋ฃ๋์์์ ์๋ฆฌ๋ ๋ช
๋ น ์ค๋ฅ๊ฐ ๋ฐ์ํ ์ ์์ต๋๋ค. ์ด ๋์์ ์์๋ ๊ฒ์ด๋ฉฐ ํด๋ผ์ด์ธํธ๊ฐ Session.abortTransaction()
๋ฅผ ํธ์ถํ์ง ์์ ๊ฒฝ์ฐ์๋ ๋ฐ์ํฉ๋๋ค. ์ฌ์ฉ์ ์ง์ ์ค๋ฅ ์ฒ๋ฆฌ๋ฅผ ํตํฉํ๋ ค๋ฉด ํธ๋์ญ์
์์ Core API๋ฅผ ์ฌ์ฉํ์ธ์.
์ฝ๋ฐฑ Callback API API ๋ ํน์ ์ค๋ฅ์ ๋ํ ์ฌ์๋ ๋ก์ง์ ํตํฉํฉ๋๋ค. ์ด์ ์ ๋ TransientTransactionError ๋๋ UnknownTransactionCommitResult ์ปค๋ฐ ์ค๋ฅ ํ์ ํธ๋์ญ์ ์ ๋ค์ ์คํํ๋ ค๊ณ ์๋ํฉ๋๋ค.
MongoDB 6.2๋ถํฐ ์๋ฒ๋ TransactionTooLargeForCache ์ค๋ฅ๋ฅผ ์์ ํ๋ ๊ฒฝ์ฐ ํธ๋์ญ์ ์ ์ฌ์๋ํ์ง ์์ต๋๋ค.
์ค์
MongoDB ๋ฒ์ ์ ๋ง๋ MongoDB ๋๋ผ์ด๋ฒ๋ฅผ ์ฌ์ฉํ์ธ์.
๋๋ผ์ด๋ฒ๋ฅผ ์ฌ์ฉํ ๋ ํธ๋์ญ์ ์ ๊ฐ ์์ ์ ๊ฐ ์์ ์ ์ธ์ ์ ์ ๋ฌํด์ผ ํฉ๋๋ค.
ํธ๋์ญ์ ์ ์์ ์ ํธ๋์ญ์ ์์ค์ ์ฝ๊ธฐ ๊ณ ๋ ค, ํธ๋์ญ์ ์์ค์ ์ฐ๊ธฐ ๊ณ ๋ ค, ํธ๋์ญ์ ์์ค์ ์ฝ๊ธฐ ์ค์ ์ ์ฌ์ฉํฉ๋๋ค.
ํธ๋์ญ์ ์์ ์์์ ๋๋ ๋ช ์์ ์ผ๋ก ์ปฌ๋ ์ ์ ๋ง๋ค ์ ์์ต๋๋ค. ํธ๋์ญ์ ์์ ์ปฌ๋ ์ ๋ฐ ์ธ๋ฑ์ค ์์ฑ์ ์ฐธ์กฐํ์ธ์.
// The mongocxx::instance constructor and destructor initialize and shut down the driver, // respectively. Therefore, a mongocxx::instance must be created before using the driver and // must remain alive for as long as the driver is in use. mongocxx::instance inst{}; // For a replica set, include the replica set name and a seedlist of the members in the URI // string; e.g. // uriString = // 'mongodb://mongodb0.example.com:27017,mongodb1.example.com:27017/?replicaSet=myRepl' // For a sharded cluster, connect to the mongos instances; e.g. // uriString = 'mongodb://mongos0.example.com:27017,mongos1.example.com:27017/' mongocxx::client client{mongocxx::uri{"mongodb://localhost/?replicaSet=repl0"}}; // Prepare to set majority write explicitly. Note: on Atlas deployments this won't always be // needed. The suggested Atlas connection string includes majority write concern by default. write_concern wc_majority{}; wc_majority.acknowledge_level(write_concern::level::k_majority); // Prereq: Create collections. auto foo = client["mydb1"]["foo"]; auto bar = client["mydb2"]["bar"]; try { options::insert opts; opts.write_concern(wc_majority); foo.insert_one(make_document(kvp("abc", 0)), opts); bar.insert_one(make_document(kvp("xyz", 0)), opts); } catch (mongocxx::exception const& e) { std::cout << "An exception occurred while inserting: " << e.what() << std::endl; return EXIT_FAILURE; } // Step 1: Define the callback that specifies the sequence of operations to perform inside the // transactions. client_session::with_transaction_cb callback = [&](client_session* session) { // Important:: You must pass the session to the operations. foo.insert_one(*session, make_document(kvp("abc", 1))); bar.insert_one(*session, make_document(kvp("xyz", 999))); }; // Step 2: Start a client session auto session = client.start_session(); // Step 3: Use with_transaction to start a transaction, execute the callback, // and commit (or abort on error). try { options::transaction opts; opts.write_concern(wc_majority); session.with_transaction(callback, opts); } catch (mongocxx::exception const& e) { std::cout << "An exception occurred: " << e.what() << std::endl; return EXIT_FAILURE; } return EXIT_SUCCESS;
์ด ์์์๋ ํธ๋์ญ์ API์ ์ฃผ์ ๊ตฌ์ฑ์์๋ฅผ ๊ฐ์กฐํฉ๋๋ค. ํนํ ์ฝ๋ฐฑ API๋ฅผ ์ฌ์ฉํฉ๋๋ค. ์ฝ๋ฐฑ API:
ํธ๋์ญ์ ์ ์์ํฉ๋๋ค.
์ง์ ๋ ์์ ์ ์คํํฉ๋๋ค.
๊ฒฐ๊ณผ๋ฅผ ์ปค๋ฐํ๊ฑฐ๋ ์ค๋ฅ๊ฐ ๋ฐ์ํ์ฌ ํธ๋์ญ์ ์ ์ข ๋ฃํฉ๋๋ค.
DuplicateKeyError
์ ๊ฐ์ ์๋ฒ ์ธก ์์
์ ์ค๋ฅ๋ก ์ธํด ํธ๋์ญ์
์ด ์ข
๋ฃ๋๊ณ ์ฌ์ฉ์์๊ฒ ํธ๋์ญ์
์ด ์ข
๋ฃ๋์์์ ์๋ฆฌ๋ ๋ช
๋ น ์ค๋ฅ๊ฐ ๋ฐ์ํ ์ ์์ต๋๋ค. ์ด ๋์์ ์์๋ ๊ฒ์ด๋ฉฐ ํด๋ผ์ด์ธํธ๊ฐ Session.abortTransaction()
๋ฅผ ํธ์ถํ์ง ์์ ๊ฒฝ์ฐ์๋ ๋ฐ์ํฉ๋๋ค. ์ฌ์ฉ์ ์ง์ ์ค๋ฅ ์ฒ๋ฆฌ๋ฅผ ํตํฉํ๋ ค๋ฉด ํธ๋์ญ์
์์ Core API๋ฅผ ์ฌ์ฉํ์ธ์.
์ฝ๋ฐฑ Callback API API ๋ ํน์ ์ค๋ฅ์ ๋ํ ์ฌ์๋ ๋ก์ง์ ํตํฉํฉ๋๋ค. ์ด์ ์ ๋ TransientTransactionError ๋๋ UnknownTransactionCommitResult ์ปค๋ฐ ์ค๋ฅ ํ์ ํธ๋์ญ์ ์ ๋ค์ ์คํํ๋ ค๊ณ ์๋ํฉ๋๋ค.
MongoDB 6.2๋ถํฐ ์๋ฒ๋ TransactionTooLargeForCache ์ค๋ฅ๋ฅผ ์์ ํ๋ ๊ฒฝ์ฐ ํธ๋์ญ์ ์ ์ฌ์๋ํ์ง ์์ต๋๋ค.
์ค์
MongoDB ๋ฒ์ ์ ๋ง๋ MongoDB ๋๋ผ์ด๋ฒ๋ฅผ ์ฌ์ฉํ์ธ์.
๋๋ผ์ด๋ฒ๋ฅผ ์ฌ์ฉํ ๋ ํธ๋์ญ์ ์ ๊ฐ ์์ ์ ๊ฐ ์์ ์ ์ธ์ ์ ์ ๋ฌํด์ผ ํฉ๋๋ค.
ํธ๋์ญ์ ์ ์์ ์ ํธ๋์ญ์ ์์ค์ ์ฝ๊ธฐ ๊ณ ๋ ค, ํธ๋์ญ์ ์์ค์ ์ฐ๊ธฐ ๊ณ ๋ ค, ํธ๋์ญ์ ์์ค์ ์ฝ๊ธฐ ์ค์ ์ ์ฌ์ฉํฉ๋๋ค.
ํธ๋์ญ์ ์์ ์์์ ๋๋ ๋ช ์์ ์ผ๋ก ์ปฌ๋ ์ ์ ๋ง๋ค ์ ์์ต๋๋ค. ํธ๋์ญ์ ์์ ์ปฌ๋ ์ ๋ฐ ์ธ๋ฑ์ค ์์ฑ์ ์ฐธ์กฐํ์ธ์.
// For a replica set, include the replica set name and a seedlist of the members in the URI string; e.g. // string uri = "mongodb://mongodb0.example.com:27017,mongodb1.example.com:27017/?replicaSet=myRepl"; // For a sharded cluster, connect to the mongos instances; e.g. // string uri = "mongodb://mongos0.example.com:27017,mongos1.example.com:27017/"; var client = new MongoClient(connectionString); // Prereq: Create collections. var database1 = client.GetDatabase("mydb1"); var collection1 = database1.GetCollection<BsonDocument>("foo").WithWriteConcern(WriteConcern.WMajority); collection1.InsertOne(new BsonDocument("abc", 0)); var database2 = client.GetDatabase("mydb2"); var collection2 = database2.GetCollection<BsonDocument>("bar").WithWriteConcern(WriteConcern.WMajority); collection2.InsertOne(new BsonDocument("xyz", 0)); // Step 1: Start a client session. using (var session = client.StartSession()) { // Step 2: Optional. Define options to use for the transaction. var transactionOptions = new TransactionOptions( writeConcern: WriteConcern.WMajority); // Step 3: Define the sequence of operations to perform inside the transactions var cancellationToken = CancellationToken.None; // normally a real token would be used result = session.WithTransaction( (s, ct) => { try { collection1.InsertOne(s, new BsonDocument("abc", 1), cancellationToken: ct); collection2.InsertOne(s, new BsonDocument("xyz", 999), cancellationToken: ct); } catch (MongoWriteException) { // Do something in response to the exception throw; // NOTE: You must rethrow the exception otherwise an infinite loop can occur. } return "Inserted into collections in different databases"; }, transactionOptions, cancellationToken); }
์ด ์์์๋ ํธ๋์ญ์ API์ ์ฃผ์ ๊ตฌ์ฑ์์๋ฅผ ๊ฐ์กฐํฉ๋๋ค. ํนํ ์ฝ๋ฐฑ API๋ฅผ ์ฌ์ฉํฉ๋๋ค. ์ฝ๋ฐฑ API:
ํธ๋์ญ์ ์ ์์ํฉ๋๋ค.
์ง์ ๋ ์์ ์ ์คํํฉ๋๋ค.
๊ฒฐ๊ณผ๋ฅผ ์ปค๋ฐํ๊ฑฐ๋ ์ค๋ฅ๊ฐ ๋ฐ์ํ์ฌ ํธ๋์ญ์ ์ ์ข ๋ฃํฉ๋๋ค.
DuplicateKeyError
์ ๊ฐ์ ์๋ฒ ์ธก ์์
์ ์ค๋ฅ๋ก ์ธํด ํธ๋์ญ์
์ด ์ข
๋ฃ๋๊ณ ์ฌ์ฉ์์๊ฒ ํธ๋์ญ์
์ด ์ข
๋ฃ๋์์์ ์๋ฆฌ๋ ๋ช
๋ น ์ค๋ฅ๊ฐ ๋ฐ์ํ ์ ์์ต๋๋ค. ์ด ๋์์ ์์๋ ๊ฒ์ด๋ฉฐ ํด๋ผ์ด์ธํธ๊ฐ Session.abortTransaction()
๋ฅผ ํธ์ถํ์ง ์์ ๊ฒฝ์ฐ์๋ ๋ฐ์ํฉ๋๋ค. ์ฌ์ฉ์ ์ง์ ์ค๋ฅ ์ฒ๋ฆฌ๋ฅผ ํตํฉํ๋ ค๋ฉด ํธ๋์ญ์
์์ Core API๋ฅผ ์ฌ์ฉํ์ธ์.
์ฝ๋ฐฑ Callback API API ๋ ํน์ ์ค๋ฅ์ ๋ํ ์ฌ์๋ ๋ก์ง์ ํตํฉํฉ๋๋ค. ์ด์ ์ ๋ TransientTransactionError ๋๋ UnknownTransactionCommitResult ์ปค๋ฐ ์ค๋ฅ ํ์ ํธ๋์ญ์ ์ ๋ค์ ์คํํ๋ ค๊ณ ์๋ํฉ๋๋ค.
MongoDB 6.2๋ถํฐ ์๋ฒ๋ TransactionTooLargeForCache ์ค๋ฅ๋ฅผ ์์ ํ๋ ๊ฒฝ์ฐ ํธ๋์ญ์ ์ ์ฌ์๋ํ์ง ์์ต๋๋ค.
์ค์
MongoDB ๋ฒ์ ์ ๋ง๋ MongoDB ๋๋ผ์ด๋ฒ๋ฅผ ์ฌ์ฉํ์ธ์.
๋๋ผ์ด๋ฒ๋ฅผ ์ฌ์ฉํ ๋ ํธ๋์ญ์ ์ ๊ฐ ์์ ์ ๊ฐ ์์ ์ ์ธ์ ์ ์ ๋ฌํด์ผ ํฉ๋๋ค.
ํธ๋์ญ์ ์ ์์ ์ ํธ๋์ญ์ ์์ค์ ์ฝ๊ธฐ ๊ณ ๋ ค, ํธ๋์ญ์ ์์ค์ ์ฐ๊ธฐ ๊ณ ๋ ค, ํธ๋์ญ์ ์์ค์ ์ฝ๊ธฐ ์ค์ ์ ์ฌ์ฉํฉ๋๋ค.
ํธ๋์ญ์ ์์ ์์์ ๋๋ ๋ช ์์ ์ผ๋ก ์ปฌ๋ ์ ์ ๋ง๋ค ์ ์์ต๋๋ค. ํธ๋์ญ์ ์์ ์ปฌ๋ ์ ๋ฐ ์ธ๋ฑ์ค ์์ฑ์ ์ฐธ์กฐํ์ธ์.
// WithTransactionExample is an example of using the Session.WithTransaction function. func WithTransactionExample(ctx context.Context) error { // For a replica set, include the replica set name and a seedlist of the members in the URI string; e.g. // uri := "mongodb://mongodb0.example.com:27017,mongodb1.example.com:27017/?replicaSet=myRepl" // For a sharded cluster, connect to the mongos instances; e.g. // uri := "mongodb://mongos0.example.com:27017,mongos1.example.com:27017/" uri := mtest.ClusterURI() clientOpts := options.Client().ApplyURI(uri) client, err := mongo.Connect(clientOpts) if err != nil { return err } defer func() { _ = client.Disconnect(ctx) }() // Prereq: Create collections. wcMajority := writeconcern.Majority() wcMajorityCollectionOpts := options.Collection().SetWriteConcern(wcMajority) fooColl := client.Database("mydb1").Collection("foo", wcMajorityCollectionOpts) barColl := client.Database("mydb1").Collection("bar", wcMajorityCollectionOpts) // Step 1: Define the callback that specifies the sequence of operations to perform inside the transaction. callback := func(sesctx context.Context) (interface{}, error) { // Important: You must pass sesctx as the Context parameter to the operations for them to be executed in the // transaction. if _, err := fooColl.InsertOne(sesctx, bson.D{{"abc", 1}}); err != nil { return nil, err } if _, err := barColl.InsertOne(sesctx, bson.D{{"xyz", 999}}); err != nil { return nil, err } return nil, nil } // Step 2: Start a session and run the callback using WithTransaction. session, err := client.StartSession() if err != nil { return err } defer session.EndSession(ctx) result, err := session.WithTransaction(ctx, callback) if err != nil { return err } log.Printf("result: %v\n", result) return nil }
์ด ์์์๋ ํธ๋์ญ์ API์ ์ฃผ์ ๊ตฌ์ฑ์์๋ฅผ ๊ฐ์กฐํฉ๋๋ค. ํนํ ์ฝ๋ฐฑ API๋ฅผ ์ฌ์ฉํฉ๋๋ค. ์ฝ๋ฐฑ API:
ํธ๋์ญ์ ์ ์์ํฉ๋๋ค.
์ง์ ๋ ์์ ์ ์คํํฉ๋๋ค.
๊ฒฐ๊ณผ๋ฅผ ์ปค๋ฐํ๊ฑฐ๋ ์ค๋ฅ๊ฐ ๋ฐ์ํ์ฌ ํธ๋์ญ์ ์ ์ข ๋ฃํฉ๋๋ค.
DuplicateKeyError
์ ๊ฐ์ ์๋ฒ ์ธก ์์
์ ์ค๋ฅ๋ก ์ธํด ํธ๋์ญ์
์ด ์ข
๋ฃ๋๊ณ ์ฌ์ฉ์์๊ฒ ํธ๋์ญ์
์ด ์ข
๋ฃ๋์์์ ์๋ฆฌ๋ ๋ช
๋ น ์ค๋ฅ๊ฐ ๋ฐ์ํ ์ ์์ต๋๋ค. ์ด ๋์์ ์์๋ ๊ฒ์ด๋ฉฐ ํด๋ผ์ด์ธํธ๊ฐ Session.abortTransaction()
๋ฅผ ํธ์ถํ์ง ์์ ๊ฒฝ์ฐ์๋ ๋ฐ์ํฉ๋๋ค. ์ฌ์ฉ์ ์ง์ ์ค๋ฅ ์ฒ๋ฆฌ๋ฅผ ํตํฉํ๋ ค๋ฉด ํธ๋์ญ์
์์ Core API๋ฅผ ์ฌ์ฉํ์ธ์.
์ฝ๋ฐฑ Callback API API ๋ ํน์ ์ค๋ฅ์ ๋ํ ์ฌ์๋ ๋ก์ง์ ํตํฉํฉ๋๋ค. ์ด์ ์ ๋ TransientTransactionError ๋๋ UnknownTransactionCommitResult ์ปค๋ฐ ์ค๋ฅ ํ์ ํธ๋์ญ์ ์ ๋ค์ ์คํํ๋ ค๊ณ ์๋ํฉ๋๋ค.
MongoDB 6.2๋ถํฐ ์๋ฒ๋ TransactionTooLargeForCache ์ค๋ฅ๋ฅผ ์์ ํ๋ ๊ฒฝ์ฐ ํธ๋์ญ์ ์ ์ฌ์๋ํ์ง ์์ต๋๋ค.
์ค์
MongoDB ๋ฒ์ ์ ๋ง๋ MongoDB ๋๋ผ์ด๋ฒ๋ฅผ ์ฌ์ฉํ์ธ์.
๋๋ผ์ด๋ฒ๋ฅผ ์ฌ์ฉํ ๋ ํธ๋์ญ์ ์ ๊ฐ ์์ ์ ๊ฐ ์์ ์ ์ธ์ ์ ์ ๋ฌํด์ผ ํฉ๋๋ค.
ํธ๋์ญ์ ์ ์์ ์ ํธ๋์ญ์ ์์ค์ ์ฝ๊ธฐ ๊ณ ๋ ค, ํธ๋์ญ์ ์์ค์ ์ฐ๊ธฐ ๊ณ ๋ ค, ํธ๋์ญ์ ์์ค์ ์ฝ๊ธฐ ์ค์ ์ ์ฌ์ฉํฉ๋๋ค.
ํธ๋์ญ์ ์์ ์์์ ๋๋ ๋ช ์์ ์ผ๋ก ์ปฌ๋ ์ ์ ๋ง๋ค ์ ์์ต๋๋ค. ํธ๋์ญ์ ์์ ์ปฌ๋ ์ ๋ฐ ์ธ๋ฑ์ค ์์ฑ์ ์ฐธ์กฐํ์ธ์.
/* For a replica set, include the replica set name and a seedlist of the members in the URI string; e.g. String uri = "mongodb://mongodb0.example.com:27017,mongodb1.example.com:27017/admin?replicaSet=myRepl"; For a sharded cluster, connect to the mongos instances. For example: String uri = "mongodb://mongos0.example.com:27017,mongos1.example.com:27017:27017/admin"; */ final MongoClient client = MongoClients.create(uri); /* Create collections. */ client.getDatabase("mydb1").getCollection("foo") .withWriteConcern(WriteConcern.MAJORITY).insertOne(new Document("abc", 0)); client.getDatabase("mydb2").getCollection("bar") .withWriteConcern(WriteConcern.MAJORITY).insertOne(new Document("xyz", 0)); /* Step 1: Start a client session. */ final ClientSession clientSession = client.startSession(); /* Step 2: Optional. Define options to use for the transaction. */ TransactionOptions txnOptions = TransactionOptions.builder() .writeConcern(WriteConcern.MAJORITY) .build(); /* Step 3: Define the sequence of operations to perform inside the transactions. */ TransactionBody txnBody = new TransactionBody<String>() { public String execute() { MongoCollection<Document> coll1 = client.getDatabase("mydb1").getCollection("foo"); MongoCollection<Document> coll2 = client.getDatabase("mydb2").getCollection("bar"); /* Important:: You must pass the session to the operations. */ coll1.insertOne(clientSession, new Document("abc", 1)); coll2.insertOne(clientSession, new Document("xyz", 999)); return "Inserted into collections in different databases"; } }; try { /* Step 4: Use .withTransaction() to start a transaction, execute the callback, and commit (or abort on error). */ clientSession.withTransaction(txnBody, txnOptions); } catch (RuntimeException e) { // some error handling } finally { clientSession.close(); }
์ด ์์์๋ ํธ๋์ญ์ API์ ์ฃผ์ ๊ตฌ์ฑ์์๋ฅผ ๊ฐ์กฐํฉ๋๋ค. ํนํ ์ฝ๋ฐฑ API๋ฅผ ์ฌ์ฉํฉ๋๋ค. ์ฝ๋ฐฑ API:
ํธ๋์ญ์ ์ ์์ํฉ๋๋ค.
์ง์ ๋ ์์ ์ ์คํํฉ๋๋ค.
๊ฒฐ๊ณผ๋ฅผ ์ปค๋ฐํ๊ฑฐ๋ ์ค๋ฅ๊ฐ ๋ฐ์ํ์ฌ ํธ๋์ญ์ ์ ์ข ๋ฃํฉ๋๋ค.
DuplicateKeyError
์ ๊ฐ์ ์๋ฒ ์ธก ์์
์ ์ค๋ฅ๋ก ์ธํด ํธ๋์ญ์
์ด ์ข
๋ฃ๋๊ณ ์ฌ์ฉ์์๊ฒ ํธ๋์ญ์
์ด ์ข
๋ฃ๋์์์ ์๋ฆฌ๋ ๋ช
๋ น ์ค๋ฅ๊ฐ ๋ฐ์ํ ์ ์์ต๋๋ค. ์ด ๋์์ ์์๋ ๊ฒ์ด๋ฉฐ ํด๋ผ์ด์ธํธ๊ฐ Session.abortTransaction()
๋ฅผ ํธ์ถํ์ง ์์ ๊ฒฝ์ฐ์๋ ๋ฐ์ํฉ๋๋ค. ์ฌ์ฉ์ ์ง์ ์ค๋ฅ ์ฒ๋ฆฌ๋ฅผ ํตํฉํ๋ ค๋ฉด ํธ๋์ญ์
์์ Core API๋ฅผ ์ฌ์ฉํ์ธ์.
์ฝ๋ฐฑ Callback API API ๋ ํน์ ์ค๋ฅ์ ๋ํ ์ฌ์๋ ๋ก์ง์ ํตํฉํฉ๋๋ค. ์ด์ ์ ๋ TransientTransactionError ๋๋ UnknownTransactionCommitResult ์ปค๋ฐ ์ค๋ฅ ํ์ ํธ๋์ญ์ ์ ๋ค์ ์คํํ๋ ค๊ณ ์๋ํฉ๋๋ค.
MongoDB 6.2๋ถํฐ ์๋ฒ๋ TransactionTooLargeForCache ์ค๋ฅ๋ฅผ ์์ ํ๋ ๊ฒฝ์ฐ ํธ๋์ญ์ ์ ์ฌ์๋ํ์ง ์์ต๋๋ค.
์ค์
MongoDB ๋ฒ์ ์ ๋ง๋ MongoDB ๋๋ผ์ด๋ฒ๋ฅผ ์ฌ์ฉํ์ธ์.
๋๋ผ์ด๋ฒ๋ฅผ ์ฌ์ฉํ ๋ ํธ๋์ญ์ ์ ๊ฐ ์์ ์ ๊ฐ ์์ ์ ์ธ์ ์ ์ ๋ฌํด์ผ ํฉ๋๋ค.
ํธ๋์ญ์ ์ ์์ ์ ํธ๋์ญ์ ์์ค์ ์ฝ๊ธฐ ๊ณ ๋ ค, ํธ๋์ญ์ ์์ค์ ์ฐ๊ธฐ ๊ณ ๋ ค, ํธ๋์ญ์ ์์ค์ ์ฝ๊ธฐ ์ค์ ์ ์ฌ์ฉํฉ๋๋ค.
ํธ๋์ญ์ ์์ ์์์ ๋๋ ๋ช ์์ ์ผ๋ก ์ปฌ๋ ์ ์ ๋ง๋ค ์ ์์ต๋๋ค. ํธ๋์ญ์ ์์ ์ปฌ๋ ์ ๋ฐ ์ธ๋ฑ์ค ์์ฑ์ ์ฐธ์กฐํ์ธ์.
# For a replica set, include the replica set name and a seedlist of the members in the URI string; e.g. # uriString = 'mongodb://mongodb0.example.com:27017,mongodb1.example.com:27017/?replicaSet=myRepl' # For a sharded cluster, connect to the mongos instances; e.g. # uriString = 'mongodb://mongos0.example.com:27017,mongos1.example.com:27017/' client = AsyncIOMotorClient(uriString) wc_majority = WriteConcern("majority", wtimeout=1000) # Prereq: Create collections. await client.get_database("mydb1", write_concern=wc_majority).foo.insert_one({"abc": 0}) await client.get_database("mydb2", write_concern=wc_majority).bar.insert_one({"xyz": 0}) # Step 1: Define the callback that specifies the sequence of operations to perform inside the transactions. async def callback(my_session): collection_one = my_session.client.mydb1.foo collection_two = my_session.client.mydb2.bar # Important:: You must pass the session to the operations. await collection_one.insert_one({"abc": 1}, session=my_session) await collection_two.insert_one({"xyz": 999}, session=my_session) # Step 2: Start a client session. async with await client.start_session() as session: # Step 3: Use with_transaction to start a transaction, execute the callback, and commit (or abort on error). await session.with_transaction( callback, read_concern=ReadConcern("local"), write_concern=wc_majority, read_preference=ReadPreference.PRIMARY, )
์ด ์์์๋ ํธ๋์ญ์ API์ ์ฃผ์ ๊ตฌ์ฑ์์๋ฅผ ๊ฐ์กฐํฉ๋๋ค. ํนํ ์ฝ๋ฐฑ API๋ฅผ ์ฌ์ฉํฉ๋๋ค. ์ฝ๋ฐฑ API:
ํธ๋์ญ์ ์ ์์ํฉ๋๋ค.
์ง์ ๋ ์์ ์ ์คํํฉ๋๋ค.
๊ฒฐ๊ณผ๋ฅผ ์ปค๋ฐํ๊ฑฐ๋ ์ค๋ฅ๊ฐ ๋ฐ์ํ์ฌ ํธ๋์ญ์ ์ ์ข ๋ฃํฉ๋๋ค.
DuplicateKeyError
์ ๊ฐ์ ์๋ฒ ์ธก ์์
์ ์ค๋ฅ๋ก ์ธํด ํธ๋์ญ์
์ด ์ข
๋ฃ๋๊ณ ์ฌ์ฉ์์๊ฒ ํธ๋์ญ์
์ด ์ข
๋ฃ๋์์์ ์๋ฆฌ๋ ๋ช
๋ น ์ค๋ฅ๊ฐ ๋ฐ์ํ ์ ์์ต๋๋ค. ์ด ๋์์ ์์๋ ๊ฒ์ด๋ฉฐ ํด๋ผ์ด์ธํธ๊ฐ Session.abortTransaction()
๋ฅผ ํธ์ถํ์ง ์์ ๊ฒฝ์ฐ์๋ ๋ฐ์ํฉ๋๋ค. ์ฌ์ฉ์ ์ง์ ์ค๋ฅ ์ฒ๋ฆฌ๋ฅผ ํตํฉํ๋ ค๋ฉด ํธ๋์ญ์
์์ Core API๋ฅผ ์ฌ์ฉํ์ธ์.
์ฝ๋ฐฑ Callback API API ๋ ํน์ ์ค๋ฅ์ ๋ํ ์ฌ์๋ ๋ก์ง์ ํตํฉํฉ๋๋ค. ์ด์ ์ ๋ TransientTransactionError ๋๋ UnknownTransactionCommitResult ์ปค๋ฐ ์ค๋ฅ ํ์ ํธ๋์ญ์ ์ ๋ค์ ์คํํ๋ ค๊ณ ์๋ํฉ๋๋ค.
MongoDB 6.2๋ถํฐ ์๋ฒ๋ TransactionTooLargeForCache ์ค๋ฅ๋ฅผ ์์ ํ๋ ๊ฒฝ์ฐ ํธ๋์ญ์ ์ ์ฌ์๋ํ์ง ์์ต๋๋ค.
์ค์
MongoDB ๋ฒ์ ์ ๋ง๋ MongoDB ๋๋ผ์ด๋ฒ๋ฅผ ์ฌ์ฉํ์ธ์.
๋๋ผ์ด๋ฒ๋ฅผ ์ฌ์ฉํ ๋ ํธ๋์ญ์ ์ ๊ฐ ์์ ์ ๊ฐ ์์ ์ ์ธ์ ์ ์ ๋ฌํด์ผ ํฉ๋๋ค.
ํธ๋์ญ์ ์ ์์ ์ ํธ๋์ญ์ ์์ค์ ์ฝ๊ธฐ ๊ณ ๋ ค, ํธ๋์ญ์ ์์ค์ ์ฐ๊ธฐ ๊ณ ๋ ค, ํธ๋์ญ์ ์์ค์ ์ฝ๊ธฐ ์ค์ ์ ์ฌ์ฉํฉ๋๋ค.
ํธ๋์ญ์ ์์ ์์์ ๋๋ ๋ช ์์ ์ผ๋ก ์ปฌ๋ ์ ์ ๋ง๋ค ์ ์์ต๋๋ค. ํธ๋์ญ์ ์์ ์ปฌ๋ ์ ๋ฐ ์ธ๋ฑ์ค ์์ฑ์ ์ฐธ์กฐํ์ธ์.
// For a replica set, include the replica set name and a seedlist of the members in the URI string; e.g. // const uri = 'mongodb://mongodb0.example.com:27017,mongodb1.example.com:27017/?replicaSet=myRepl' // For a sharded cluster, connect to the mongos instances; e.g. // const uri = 'mongodb://mongos0.example.com:27017,mongos1.example.com:27017/' const client = new MongoClient(uri); await client.connect(); // Prereq: Create collections. await client .db('mydb1') .collection('foo') .insertOne({ abc: 0 }, { writeConcern: { w: 'majority' } }); await client .db('mydb2') .collection('bar') .insertOne({ xyz: 0 }, { writeConcern: { w: 'majority' } }); // Step 1: Start a Client Session const session = client.startSession(); // Step 2: Optional. Define options to use for the transaction const transactionOptions = { readPreference: 'primary', readConcern: { level: 'local' }, writeConcern: { w: 'majority' } }; // Step 3: Use withTransaction to start a transaction, execute the callback, and commit (or abort on error) // Note: The callback for withTransaction MUST be async and/or return a Promise. try { await session.withTransaction(async () => { const coll1 = client.db('mydb1').collection('foo'); const coll2 = client.db('mydb2').collection('bar'); // Important:: You must pass the session to the operations await coll1.insertOne({ abc: 1 }, { session }); await coll2.insertOne({ xyz: 999 }, { session }); }, transactionOptions); } finally { await session.endSession(); await client.close(); }
์ด ์์์๋ ํธ๋์ญ์ API์ ์ฃผ์ ๊ตฌ์ฑ์์๋ฅผ ๊ฐ์กฐํฉ๋๋ค. ํนํ ์ฝ๋ฐฑ API๋ฅผ ์ฌ์ฉํฉ๋๋ค. ์ฝ๋ฐฑ API:
ํธ๋์ญ์ ์ ์์ํฉ๋๋ค.
์ง์ ๋ ์์ ์ ์คํํฉ๋๋ค.
๊ฒฐ๊ณผ๋ฅผ ์ปค๋ฐํ๊ฑฐ๋ ์ค๋ฅ๊ฐ ๋ฐ์ํ์ฌ ํธ๋์ญ์ ์ ์ข ๋ฃํฉ๋๋ค.
DuplicateKeyError
์ ๊ฐ์ ์๋ฒ ์ธก ์์
์ ์ค๋ฅ๋ก ์ธํด ํธ๋์ญ์
์ด ์ข
๋ฃ๋๊ณ ์ฌ์ฉ์์๊ฒ ํธ๋์ญ์
์ด ์ข
๋ฃ๋์์์ ์๋ฆฌ๋ ๋ช
๋ น ์ค๋ฅ๊ฐ ๋ฐ์ํ ์ ์์ต๋๋ค. ์ด ๋์์ ์์๋ ๊ฒ์ด๋ฉฐ ํด๋ผ์ด์ธํธ๊ฐ Session.abortTransaction()
๋ฅผ ํธ์ถํ์ง ์์ ๊ฒฝ์ฐ์๋ ๋ฐ์ํฉ๋๋ค. ์ฌ์ฉ์ ์ง์ ์ค๋ฅ ์ฒ๋ฆฌ๋ฅผ ํตํฉํ๋ ค๋ฉด ํธ๋์ญ์
์์ Core API๋ฅผ ์ฌ์ฉํ์ธ์.
์ฝ๋ฐฑ Callback API API ๋ ํน์ ์ค๋ฅ์ ๋ํ ์ฌ์๋ ๋ก์ง์ ํตํฉํฉ๋๋ค. ์ด์ ์ ๋ TransientTransactionError ๋๋ UnknownTransactionCommitResult ์ปค๋ฐ ์ค๋ฅ ํ์ ํธ๋์ญ์ ์ ๋ค์ ์คํํ๋ ค๊ณ ์๋ํฉ๋๋ค.
MongoDB 6.2๋ถํฐ ์๋ฒ๋ TransactionTooLargeForCache ์ค๋ฅ๋ฅผ ์์ ํ๋ ๊ฒฝ์ฐ ํธ๋์ญ์ ์ ์ฌ์๋ํ์ง ์์ต๋๋ค.
์ค์
MongoDB ๋ฒ์ ์ ๋ง๋ MongoDB ๋๋ผ์ด๋ฒ๋ฅผ ์ฌ์ฉํ์ธ์.
๋๋ผ์ด๋ฒ๋ฅผ ์ฌ์ฉํ ๋ ํธ๋์ญ์ ์ ๊ฐ ์์ ์ ๊ฐ ์์ ์ ์ธ์ ์ ์ ๋ฌํด์ผ ํฉ๋๋ค.
ํธ๋์ญ์ ์ ์์ ์ ํธ๋์ญ์ ์์ค์ ์ฝ๊ธฐ ๊ณ ๋ ค, ํธ๋์ญ์ ์์ค์ ์ฐ๊ธฐ ๊ณ ๋ ค, ํธ๋์ญ์ ์์ค์ ์ฝ๊ธฐ ์ค์ ์ ์ฌ์ฉํฉ๋๋ค.
ํธ๋์ญ์ ์์ ์์์ ๋๋ ๋ช ์์ ์ผ๋ก ์ปฌ๋ ์ ์ ๋ง๋ค ์ ์์ต๋๋ค. ํธ๋์ญ์ ์์ ์ปฌ๋ ์ ๋ฐ ์ธ๋ฑ์ค ์์ฑ์ ์ฐธ์กฐํ์ธ์.
sub runTransactionWithRetry { my ( $txnFunc, $session ) = @_; LOOP: { eval { $txnFunc->($session); # performs transaction }; if ( my $error = $@ ) { print("Transaction aborted-> Caught exception during transaction.\n"); # If transient error, retry the whole transaction if ( $error->has_error_label("TransientTransactionError") ) { print("TransientTransactionError, retrying transaction ->..\n"); redo LOOP; } else { die $error; } } } return; } sub commitWithRetry { my ($session) = @_; LOOP: { eval { $session->commit_transaction(); # Uses write concern set at transaction start. print("Transaction committed->\n"); }; if ( my $error = $@ ) { # Can retry commit if ( $error->has_error_label("UnknownTransactionCommitResult") ) { print("UnknownTransactionCommitResult, retrying commit operation ->..\n"); redo LOOP; } else { print("Error during commit ->..\n"); die $error; } } } return; } # Updates two collections in a transactions sub updateEmployeeInfo { my ($session) = @_; my $employeesCollection = $session->client->ns("hr.employees"); my $eventsCollection = $session->client->ns("reporting.events"); $session->start_transaction( { readConcern => { level => "snapshot" }, writeConcern => { w => "majority" }, readPreference => 'primary', } ); eval { $employeesCollection->update_one( { employee => 3 }, { '$set' => { status => "Inactive" } }, { session => $session}, ); $eventsCollection->insert_one( { employee => 3, status => { new => "Inactive", old => "Active" } }, { session => $session}, ); }; if ( my $error = $@ ) { print("Caught exception during transaction, aborting->\n"); $session->abort_transaction(); die $error; } commitWithRetry($session); } # Start a session my $session = $client->start_session(); eval { runTransactionWithRetry(\&updateEmployeeInfo, $session); }; if ( my $error = $@ ) { # Do something with error } $session->end_session();
์ด ์์์๋ ํธ๋์ญ์ API์ ์ฃผ์ ๊ตฌ์ฑ์์๋ฅผ ๊ฐ์กฐํฉ๋๋ค. ํนํ ์ฝ๋ฐฑ API๋ฅผ ์ฌ์ฉํฉ๋๋ค. ์ฝ๋ฐฑ API:
ํธ๋์ญ์ ์ ์์ํฉ๋๋ค.
์ง์ ๋ ์์ ์ ์คํํฉ๋๋ค.
๊ฒฐ๊ณผ๋ฅผ ์ปค๋ฐํ๊ฑฐ๋ ์ค๋ฅ๊ฐ ๋ฐ์ํ์ฌ ํธ๋์ญ์ ์ ์ข ๋ฃํฉ๋๋ค.
DuplicateKeyError
์ ๊ฐ์ ์๋ฒ ์ธก ์์
์ ์ค๋ฅ๋ก ์ธํด ํธ๋์ญ์
์ด ์ข
๋ฃ๋๊ณ ์ฌ์ฉ์์๊ฒ ํธ๋์ญ์
์ด ์ข
๋ฃ๋์์์ ์๋ฆฌ๋ ๋ช
๋ น ์ค๋ฅ๊ฐ ๋ฐ์ํ ์ ์์ต๋๋ค. ์ด ๋์์ ์์๋ ๊ฒ์ด๋ฉฐ ํด๋ผ์ด์ธํธ๊ฐ Session.abortTransaction()
๋ฅผ ํธ์ถํ์ง ์์ ๊ฒฝ์ฐ์๋ ๋ฐ์ํฉ๋๋ค. ์ฌ์ฉ์ ์ง์ ์ค๋ฅ ์ฒ๋ฆฌ๋ฅผ ํตํฉํ๋ ค๋ฉด ํธ๋์ญ์
์์ Core API๋ฅผ ์ฌ์ฉํ์ธ์.
์ฝ๋ฐฑ Callback API API ๋ ํน์ ์ค๋ฅ์ ๋ํ ์ฌ์๋ ๋ก์ง์ ํตํฉํฉ๋๋ค. ์ด์ ์ ๋ TransientTransactionError ๋๋ UnknownTransactionCommitResult ์ปค๋ฐ ์ค๋ฅ ํ์ ํธ๋์ญ์ ์ ๋ค์ ์คํํ๋ ค๊ณ ์๋ํฉ๋๋ค.
MongoDB 6.2๋ถํฐ ์๋ฒ๋ TransactionTooLargeForCache ์ค๋ฅ๋ฅผ ์์ ํ๋ ๊ฒฝ์ฐ ํธ๋์ญ์ ์ ์ฌ์๋ํ์ง ์์ต๋๋ค.
์ค์
MongoDB ๋ฒ์ ์ ๋ง๋ MongoDB ๋๋ผ์ด๋ฒ๋ฅผ ์ฌ์ฉํ์ธ์.
๋๋ผ์ด๋ฒ๋ฅผ ์ฌ์ฉํ ๋ ํธ๋์ญ์ ์ ๊ฐ ์์ ์ ๊ฐ ์์ ์ ์ธ์ ์ ์ ๋ฌํด์ผ ํฉ๋๋ค.
ํธ๋์ญ์ ์ ์์ ์ ํธ๋์ญ์ ์์ค์ ์ฝ๊ธฐ ๊ณ ๋ ค, ํธ๋์ญ์ ์์ค์ ์ฐ๊ธฐ ๊ณ ๋ ค, ํธ๋์ญ์ ์์ค์ ์ฝ๊ธฐ ์ค์ ์ ์ฌ์ฉํฉ๋๋ค.
ํธ๋์ญ์ ์์ ์์์ ๋๋ ๋ช ์์ ์ผ๋ก ์ปฌ๋ ์ ์ ๋ง๋ค ์ ์์ต๋๋ค. ํธ๋์ญ์ ์์ ์ปฌ๋ ์ ๋ฐ ์ธ๋ฑ์ค ์์ฑ์ ์ฐธ์กฐํ์ธ์.
/* * For a replica set, include the replica set name and a seedlist of the members in the URI string; e.g. * uriString = 'mongodb://mongodb0.example.com:27017,mongodb1.example.com:27017/?replicaSet=myRepl' * For a sharded cluster, connect to the mongos instances; e.g. * uriString = 'mongodb://mongos0.example.com:27017,mongos1.example.com:27017/' */ $client = new \MongoDB\Client($uriString); // Prerequisite: Create collections. $client->selectCollection( 'mydb1', 'foo', [ 'writeConcern' => new \MongoDB\Driver\WriteConcern(\MongoDB\Driver\WriteConcern::MAJORITY, 1000), ], )->insertOne(['abc' => 0]); $client->selectCollection( 'mydb2', 'bar', [ 'writeConcern' => new \MongoDB\Driver\WriteConcern(\MongoDB\Driver\WriteConcern::MAJORITY, 1000), ], )->insertOne(['xyz' => 0]); // Step 1: Define the callback that specifies the sequence of operations to perform inside the transactions. $callback = function (\MongoDB\Driver\Session $session) use ($client): void { $client ->selectCollection('mydb1', 'foo') ->insertOne(['abc' => 1], ['session' => $session]); $client ->selectCollection('mydb2', 'bar') ->insertOne(['xyz' => 999], ['session' => $session]); }; // Step 2: Start a client session. $session = $client->startSession(); // Step 3: Use with_transaction to start a transaction, execute the callback, and commit (or abort on error). \MongoDB\with_transaction($session, $callback);
์ด ์์์๋ ํธ๋์ญ์ API์ ์ฃผ์ ๊ตฌ์ฑ์์๋ฅผ ๊ฐ์กฐํฉ๋๋ค. ํนํ ์ฝ๋ฐฑ API๋ฅผ ์ฌ์ฉํฉ๋๋ค. ์ฝ๋ฐฑ API:
ํธ๋์ญ์ ์ ์์ํฉ๋๋ค.
์ง์ ๋ ์์ ์ ์คํํฉ๋๋ค.
๊ฒฐ๊ณผ๋ฅผ ์ปค๋ฐํ๊ฑฐ๋ ์ค๋ฅ๊ฐ ๋ฐ์ํ์ฌ ํธ๋์ญ์ ์ ์ข ๋ฃํฉ๋๋ค.
DuplicateKeyError
์ ๊ฐ์ ์๋ฒ ์ธก ์์
์ ์ค๋ฅ๋ก ์ธํด ํธ๋์ญ์
์ด ์ข
๋ฃ๋๊ณ ์ฌ์ฉ์์๊ฒ ํธ๋์ญ์
์ด ์ข
๋ฃ๋์์์ ์๋ฆฌ๋ ๋ช
๋ น ์ค๋ฅ๊ฐ ๋ฐ์ํ ์ ์์ต๋๋ค. ์ด ๋์์ ์์๋ ๊ฒ์ด๋ฉฐ ํด๋ผ์ด์ธํธ๊ฐ Session.abortTransaction()
๋ฅผ ํธ์ถํ์ง ์์ ๊ฒฝ์ฐ์๋ ๋ฐ์ํฉ๋๋ค. ์ฌ์ฉ์ ์ง์ ์ค๋ฅ ์ฒ๋ฆฌ๋ฅผ ํตํฉํ๋ ค๋ฉด ํธ๋์ญ์
์์ Core API๋ฅผ ์ฌ์ฉํ์ธ์.
์ฝ๋ฐฑ Callback API API ๋ ํน์ ์ค๋ฅ์ ๋ํ ์ฌ์๋ ๋ก์ง์ ํตํฉํฉ๋๋ค. ์ด์ ์ ๋ TransientTransactionError ๋๋ UnknownTransactionCommitResult ์ปค๋ฐ ์ค๋ฅ ํ์ ํธ๋์ญ์ ์ ๋ค์ ์คํํ๋ ค๊ณ ์๋ํฉ๋๋ค.
MongoDB 6.2๋ถํฐ ์๋ฒ๋ TransactionTooLargeForCache ์ค๋ฅ๋ฅผ ์์ ํ๋ ๊ฒฝ์ฐ ํธ๋์ญ์ ์ ์ฌ์๋ํ์ง ์์ต๋๋ค.
์ค์
MongoDB ๋ฒ์ ์ ๋ง๋ MongoDB ๋๋ผ์ด๋ฒ๋ฅผ ์ฌ์ฉํ์ธ์.
๋๋ผ์ด๋ฒ๋ฅผ ์ฌ์ฉํ ๋ ํธ๋์ญ์ ์ ๊ฐ ์์ ์ ๊ฐ ์์ ์ ์ธ์ ์ ์ ๋ฌํด์ผ ํฉ๋๋ค.
ํธ๋์ญ์ ์ ์์ ์ ํธ๋์ญ์ ์์ค์ ์ฝ๊ธฐ ๊ณ ๋ ค, ํธ๋์ญ์ ์์ค์ ์ฐ๊ธฐ ๊ณ ๋ ค, ํธ๋์ญ์ ์์ค์ ์ฝ๊ธฐ ์ค์ ์ ์ฌ์ฉํฉ๋๋ค.
ํธ๋์ญ์ ์์ ์์์ ๋๋ ๋ช ์์ ์ผ๋ก ์ปฌ๋ ์ ์ ๋ง๋ค ์ ์์ต๋๋ค. ํธ๋์ญ์ ์์ ์ปฌ๋ ์ ๋ฐ ์ธ๋ฑ์ค ์์ฑ์ ์ฐธ์กฐํ์ธ์.
# For a replica set, include the replica set name and a seedlist of the members in the URI string; e.g. # uriString = 'mongodb://mongodb0.example.com:27017,mongodb1.example.com:27017/?replicaSet=myRepl' # For a sharded cluster, connect to the mongos instances; e.g. # uriString = 'mongodb://mongos0.example.com:27017,mongos1.example.com:27017/' client = MongoClient(uriString) wc_majority = WriteConcern("majority", wtimeout=1000) # Prereq: Create collections. client.get_database("mydb1", write_concern=wc_majority).foo.insert_one({"abc": 0}) client.get_database("mydb2", write_concern=wc_majority).bar.insert_one({"xyz": 0}) # Step 1: Define the callback that specifies the sequence of operations to perform inside the transactions. def callback(session): collection_one = session.client.mydb1.foo collection_two = session.client.mydb2.bar # Important:: You must pass the session to the operations. collection_one.insert_one({"abc": 1}, session=session) collection_two.insert_one({"xyz": 999}, session=session) # Step 2: Start a client session. with client.start_session() as session: # Step 3: Use with_transaction to start a transaction, execute the callback, and commit (or abort on error). session.with_transaction( callback, read_concern=ReadConcern("local"), write_concern=wc_majority, read_preference=ReadPreference.PRIMARY, )
์ด ์์์๋ ํธ๋์ญ์ API์ ์ฃผ์ ๊ตฌ์ฑ์์๋ฅผ ๊ฐ์กฐํฉ๋๋ค. ํนํ ์ฝ๋ฐฑ API๋ฅผ ์ฌ์ฉํฉ๋๋ค. ์ฝ๋ฐฑ API:
ํธ๋์ญ์ ์ ์์ํฉ๋๋ค.
์ง์ ๋ ์์ ์ ์คํํฉ๋๋ค.
๊ฒฐ๊ณผ๋ฅผ ์ปค๋ฐํ๊ฑฐ๋ ์ค๋ฅ๊ฐ ๋ฐ์ํ์ฌ ํธ๋์ญ์ ์ ์ข ๋ฃํฉ๋๋ค.
DuplicateKeyError
์ ๊ฐ์ ์๋ฒ ์ธก ์์
์ ์ค๋ฅ๋ก ์ธํด ํธ๋์ญ์
์ด ์ข
๋ฃ๋๊ณ ์ฌ์ฉ์์๊ฒ ํธ๋์ญ์
์ด ์ข
๋ฃ๋์์์ ์๋ฆฌ๋ ๋ช
๋ น ์ค๋ฅ๊ฐ ๋ฐ์ํ ์ ์์ต๋๋ค. ์ด ๋์์ ์์๋ ๊ฒ์ด๋ฉฐ ํด๋ผ์ด์ธํธ๊ฐ Session.abortTransaction()
๋ฅผ ํธ์ถํ์ง ์์ ๊ฒฝ์ฐ์๋ ๋ฐ์ํฉ๋๋ค. ์ฌ์ฉ์ ์ง์ ์ค๋ฅ ์ฒ๋ฆฌ๋ฅผ ํตํฉํ๋ ค๋ฉด ํธ๋์ญ์
์์ Core API๋ฅผ ์ฌ์ฉํ์ธ์.
์ฝ๋ฐฑ Callback API API ๋ ํน์ ์ค๋ฅ์ ๋ํ ์ฌ์๋ ๋ก์ง์ ํตํฉํฉ๋๋ค. ์ด์ ์ ๋ TransientTransactionError ๋๋ UnknownTransactionCommitResult ์ปค๋ฐ ์ค๋ฅ ํ์ ํธ๋์ญ์ ์ ๋ค์ ์คํํ๋ ค๊ณ ์๋ํฉ๋๋ค.
MongoDB 6.2๋ถํฐ ์๋ฒ๋ TransactionTooLargeForCache ์ค๋ฅ๋ฅผ ์์ ํ๋ ๊ฒฝ์ฐ ํธ๋์ญ์ ์ ์ฌ์๋ํ์ง ์์ต๋๋ค.
์ค์
MongoDB ๋ฒ์ ์ ๋ง๋ MongoDB ๋๋ผ์ด๋ฒ๋ฅผ ์ฌ์ฉํ์ธ์.
๋๋ผ์ด๋ฒ๋ฅผ ์ฌ์ฉํ ๋ ํธ๋์ญ์ ์ ๊ฐ ์์ ์ ๊ฐ ์์ ์ ์ธ์ ์ ์ ๋ฌํด์ผ ํฉ๋๋ค.
ํธ๋์ญ์ ์ ์์ ์ ํธ๋์ญ์ ์์ค์ ์ฝ๊ธฐ ๊ณ ๋ ค, ํธ๋์ญ์ ์์ค์ ์ฐ๊ธฐ ๊ณ ๋ ค, ํธ๋์ญ์ ์์ค์ ์ฝ๊ธฐ ์ค์ ์ ์ฌ์ฉํฉ๋๋ค.
ํธ๋์ญ์ ์์ ์์์ ๋๋ ๋ช ์์ ์ผ๋ก ์ปฌ๋ ์ ์ ๋ง๋ค ์ ์์ต๋๋ค. ํธ๋์ญ์ ์์ ์ปฌ๋ ์ ๋ฐ ์ธ๋ฑ์ค ์์ฑ์ ์ฐธ์กฐํ์ธ์.
# For a replica set, include the replica set name and a seedlist of the members in the URI string; e.g. # uriString = 'mongodb://mongodb0.example.com:27017,mongodb1.example.com:27017/?replicaSet=myRepl' # For a sharded cluster, connect to the mongos instances; e.g. # uri_string = 'mongodb://mongos0.example.com:27017,mongos1.example.com:27017/' client = Mongo::Client.new(uri_string, write_concern: {w: :majority, wtimeout: 1000}) # Prereq: Create collections. client.use('mydb1')['foo'].insert_one(abc: 0) client.use('mydb2')['bar'].insert_one(xyz: 0) # Step 1: Define the callback that specifies the sequence of operations to perform inside the transactions. callback = Proc.new do |my_session| collection_one = client.use('mydb1')['foo'] collection_two = client.use('mydb2')['bar'] # Important: You must pass the session to the operations. collection_one.insert_one({'abc': 1}, session: my_session) collection_two.insert_one({'xyz': 999}, session: my_session) end #. Step 2: Start a client session. session = client.start_session # Step 3: Use with_transaction to start a transaction, execute the callback, and commit (or abort on error). session.with_transaction( read_concern: {level: :local}, write_concern: {w: :majority, wtimeout: 1000}, read: {mode: :primary}, &callback)
์ด ์์์๋ ํธ๋์ญ์ API์ ์ฃผ์ ๊ตฌ์ฑ์์๋ฅผ ๊ฐ์กฐํฉ๋๋ค. ํนํ ์ฝ๋ฐฑ API๋ฅผ ์ฌ์ฉํฉ๋๋ค. ์ฝ๋ฐฑ API:
ํธ๋์ญ์ ์ ์์ํฉ๋๋ค.
์ง์ ๋ ์์ ์ ์คํํฉ๋๋ค.
๊ฒฐ๊ณผ๋ฅผ ์ปค๋ฐํ๊ฑฐ๋ ์ค๋ฅ๊ฐ ๋ฐ์ํ์ฌ ํธ๋์ญ์ ์ ์ข ๋ฃํฉ๋๋ค.
DuplicateKeyError
์ ๊ฐ์ ์๋ฒ ์ธก ์์
์ ์ค๋ฅ๋ก ์ธํด ํธ๋์ญ์
์ด ์ข
๋ฃ๋๊ณ ์ฌ์ฉ์์๊ฒ ํธ๋์ญ์
์ด ์ข
๋ฃ๋์์์ ์๋ฆฌ๋ ๋ช
๋ น ์ค๋ฅ๊ฐ ๋ฐ์ํ ์ ์์ต๋๋ค. ์ด ๋์์ ์์๋ ๊ฒ์ด๋ฉฐ ํด๋ผ์ด์ธํธ๊ฐ Session.abortTransaction()
๋ฅผ ํธ์ถํ์ง ์์ ๊ฒฝ์ฐ์๋ ๋ฐ์ํฉ๋๋ค. ์ฌ์ฉ์ ์ง์ ์ค๋ฅ ์ฒ๋ฆฌ๋ฅผ ํตํฉํ๋ ค๋ฉด ํธ๋์ญ์
์์ Core API๋ฅผ ์ฌ์ฉํ์ธ์.
์ฝ๋ฐฑ Callback API API ๋ ํน์ ์ค๋ฅ์ ๋ํ ์ฌ์๋ ๋ก์ง์ ํตํฉํฉ๋๋ค. ์ด์ ์ ๋ TransientTransactionError ๋๋ UnknownTransactionCommitResult ์ปค๋ฐ ์ค๋ฅ ํ์ ํธ๋์ญ์ ์ ๋ค์ ์คํํ๋ ค๊ณ ์๋ํฉ๋๋ค.
MongoDB 6.2๋ถํฐ ์๋ฒ๋ TransactionTooLargeForCache ์ค๋ฅ๋ฅผ ์์ ํ๋ ๊ฒฝ์ฐ ํธ๋์ญ์ ์ ์ฌ์๋ํ์ง ์์ต๋๋ค.
์ค์
MongoDB ๋ฒ์ ์ ๋ง๋ MongoDB ๋๋ผ์ด๋ฒ๋ฅผ ์ฌ์ฉํ์ธ์.
๋๋ผ์ด๋ฒ๋ฅผ ์ฌ์ฉํ ๋ ํธ๋์ญ์ ์ ๊ฐ ์์ ์ ๊ฐ ์์ ์ ์ธ์ ์ ์ ๋ฌํด์ผ ํฉ๋๋ค.
ํธ๋์ญ์ ์ ์์ ์ ํธ๋์ญ์ ์์ค์ ์ฝ๊ธฐ ๊ณ ๋ ค, ํธ๋์ญ์ ์์ค์ ์ฐ๊ธฐ ๊ณ ๋ ค, ํธ๋์ญ์ ์์ค์ ์ฝ๊ธฐ ์ค์ ์ ์ฌ์ฉํฉ๋๋ค.
ํธ๋์ญ์ ์์ ์์์ ๋๋ ๋ช ์์ ์ผ๋ก ์ปฌ๋ ์ ์ ๋ง๋ค ์ ์์ต๋๋ค. ํธ๋์ญ์ ์์ ์ปฌ๋ ์ ๋ฐ ์ธ๋ฑ์ค ์์ฑ์ ์ฐธ์กฐํ์ธ์.
// For a replica set, include the replica set name and a seedlist of the members in the URI // string; e.g. let uri = "mongodb://mongodb0.example.com:27017,mongodb1.example.com:27017/? // replicaSet=myRepl"; For a sharded cluster, connect to the mongos instances; e.g. // let uri = "mongodb://mongos0.example.com:27017,mongos1.example.com:27017/"; let client = Client::with_uri_str(uri).await?; // Prereq: Create collections. CRUD operations in transactions must be on existing collections. client .database("mydb1") .collection::<Document>("foo") .insert_one(doc! { "abc": 0}) .await?; client .database("mydb2") .collection::<Document>("bar") .insert_one(doc! { "xyz": 0}) .await?; // Step 1: Define the callback that specifies the sequence of operations to perform inside the // transaction. async fn callback(session: &mut ClientSession) -> Result<()> { let collection_one = session .client() .database("mydb1") .collection::<Document>("foo"); let collection_two = session .client() .database("mydb2") .collection::<Document>("bar"); // Important: You must pass the session to the operations. collection_one .insert_one(doc! { "abc": 1 }) .session(&mut *session) .await?; collection_two .insert_one(doc! { "xyz": 999 }) .session(session) .await?; Ok(()) } // Step 2: Start a client session. let mut session = client.start_session().await?; // Step 3: Use and_run to start a transaction, execute the callback, and commit (or // abort on error). session .start_transaction() .and_run((), |session, _| callback(session).boxed()) .await?;
์ด ์์ ์์๋ core API๋ฅผ ์ฌ์ฉํฉ๋๋ค. ํต์ฌ API ์๋ TransientTransactionError
๋๋ UnknownTransactionCommitResult
์ปค๋ฐ ์ค๋ฅ์ ๋ํ ์ฌ์๋ ๋ก์ง์ด ํตํฉ๋์ด ์์ง ์์ผ๋ฏ๋ก ์ด ์์ ์๋ ์ด๋ฌํ ์ค๋ฅ์ ๋ํด ํธ๋์ญ์
์ ์ฌ์๋ํ๋ ๋ช
์์ ์ธ ๋ก์ง์ด ํฌํจ๋์ด ์์ต๋๋ค.
์ค์
MongoDB ๋ฒ์ ์ ๋ง๋ MongoDB ๋๋ผ์ด๋ฒ๋ฅผ ์ฌ์ฉํ์ธ์.
๋๋ผ์ด๋ฒ๋ฅผ ์ฌ์ฉํ ๋ ํธ๋์ญ์ ์ ๊ฐ ์์ ์ ๊ฐ ์์ ์ ์ธ์ ์ ์ ๋ฌํด์ผ ํฉ๋๋ค.
ํธ๋์ญ์ ์ ์์ ์ ํธ๋์ญ์ ์์ค์ ์ฝ๊ธฐ ๊ณ ๋ ค, ํธ๋์ญ์ ์์ค์ ์ฐ๊ธฐ ๊ณ ๋ ค, ํธ๋์ญ์ ์์ค์ ์ฝ๊ธฐ ์ค์ ์ ์ฌ์ฉํฉ๋๋ค.
ํธ๋์ญ์ ์์ ์์์ ๋๋ ๋ช ์์ ์ผ๋ก ์ปฌ๋ ์ ์ ๋ง๋ค ์ ์์ต๋๋ค. ํธ๋์ญ์ ์์ ์ปฌ๋ ์ ๋ฐ ์ธ๋ฑ์ค ์์ฑ์ ์ฐธ์กฐํ์ธ์.
/* * Copyright 2008-present MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.mongodb.scala import org.mongodb.scala.model.{Filters, Updates} import org.mongodb.scala.result.UpdateResult import scala.concurrent.Await import scala.concurrent.duration.Duration //scalastyle:off magic.number class DocumentationTransactionsExampleSpec extends RequiresMongoDBISpec { // Implicit functions that execute the Observable and return the results val waitDuration = Duration(5, "seconds") implicit class ObservableExecutor[T](observable: Observable[T]) { def execute(): Seq[T] = Await.result(observable.toFuture(), waitDuration) } implicit class SingleObservableExecutor[T](observable: SingleObservable[T]) { def execute(): T = Await.result(observable.toFuture(), waitDuration) } // end implicit functions "The Scala driver" should "be able to commit a transaction" in withClient { client => assume(serverVersionAtLeast(List(4, 0, 0)) && !hasSingleHost()) client.getDatabase("hr").drop().execute() client.getDatabase("hr").createCollection("employees").execute() client.getDatabase("hr").createCollection("events").execute() updateEmployeeInfoWithRetry(client).execute() should equal(Completed()) client.getDatabase("hr").drop().execute() should equal(Completed()) } def updateEmployeeInfo(database: MongoDatabase, observable: SingleObservable[ClientSession]): SingleObservable[ClientSession] = { observable.map(clientSession => { val employeesCollection = database.getCollection("employees") val eventsCollection = database.getCollection("events") val transactionOptions = TransactionOptions.builder() .readPreference(ReadPreference.primary()) .readConcern(ReadConcern.SNAPSHOT) .writeConcern(WriteConcern.MAJORITY) .build() clientSession.startTransaction(transactionOptions) employeesCollection.updateOne(clientSession, Filters.eq("employee", 3), Updates.set("status", "Inactive")) .subscribe((res: UpdateResult) => println(res)) eventsCollection.insertOne(clientSession, Document("employee" -> 3, "status" -> Document("new" -> "Inactive", "old" -> "Active"))) .subscribe((res: Completed) => println(res)) clientSession }) } def commitAndRetry(observable: SingleObservable[Completed]): SingleObservable[Completed] = { observable.recoverWith({ case e: MongoException if e.hasErrorLabel(MongoException.UNKNOWN_TRANSACTION_COMMIT_RESULT_LABEL) => { println("UnknownTransactionCommitResult, retrying commit operation ...") commitAndRetry(observable) } case e: Exception => { println(s"Exception during commit ...: $e") throw e } }) } def runTransactionAndRetry(observable: SingleObservable[Completed]): SingleObservable[Completed] = { observable.recoverWith({ case e: MongoException if e.hasErrorLabel(MongoException.TRANSIENT_TRANSACTION_ERROR_LABEL) => { println("TransientTransactionError, aborting transaction and retrying ...") runTransactionAndRetry(observable) } }) } def updateEmployeeInfoWithRetry(client: MongoClient): SingleObservable[Completed] = { val database = client.getDatabase("hr") val updateEmployeeInfoObservable: Observable[ClientSession] = updateEmployeeInfo(database, client.startSession()) val commitTransactionObservable: SingleObservable[Completed] = updateEmployeeInfoObservable.flatMap(clientSession => clientSession.commitTransaction()) val commitAndRetryObservable: SingleObservable[Completed] = commitAndRetry(commitTransactionObservable) runTransactionAndRetry(commitAndRetryObservable) } }
ํธ๋์ญ์ ๋ฐ ์์์ฑ
์ฌ๋ฌ ๋ฌธ์(๋จ์ผ ๋๋ ์ฌ๋ฌ ์ปฌ๋ ์ )์ ๋ํ ์ฝ๊ธฐ ๋ฐ ์ฐ๊ธฐ์ ์์์ฑ์ด ํ์ํ ์ํฉ์ ๊ฒฝ์ฐ, ๋ณต์ ๋ณธ ์ธํธ ๋ฐ ์ค๋ฉ๋ ํด๋ฌ์คํฐ์์์ ํธ๋์ญ์ ์ ํฌํจํ ๋ถ์ฐ ํธ๋์ญ์ ์ ์ง์ํฉ๋๋ค.
๋ถ์ฐ ํธ๋์ญ์ ์ ๋ค์๊ณผ ๊ฐ์ด ์์์ ์ ๋๋ค.
ํธ๋์ญ์ ์ ๋ชจ๋ ๋ฐ์ดํฐ ๋ณ๊ฒฝ ์ฌํญ์ ์ ์ฉํ๊ฑฐ๋ ๋ณ๊ฒฝ ์ฌํญ์ ๋กค๋ฐฑํฉ๋๋ค.
ํธ๋์ญ์ ์ด ์ปค๋ฐ๋๋ฉด ํธ๋์ญ์ ์์ ์ด๋ฃจ์ด์ง ๋ชจ๋ ๋ฐ์ดํฐ ๋ณ๊ฒฝ ์ฌํญ์ด ์ ์ฅ๋๊ณ ํธ๋์ญ์ ์ธ๋ถ์์ ๋ณผ ์ ์์ต๋๋ค.
ํธ๋์ญ์ ์ด ์ปค๋ฐ๋ ๋๊น์ง ํธ๋์ญ์ ์์ ๋ณ๊ฒฝ๋ ๋ฐ์ดํฐ๋ ํธ๋์ญ์ ์ธ๋ถ์ ํ์๋์ง ์์ต๋๋ค.
๊ทธ๋ฌ๋ ํธ๋์ญ์ ์ด ์ฌ๋ฌ ์ค๋์ ์ฐ๊ธฐ๋ฅผ ์ํํ๋ ๊ฒฝ์ฐ, ๋ชจ๋ ์ธ๋ถ ์ฝ๊ธฐ ์์ ์ด ์ปค๋ฐ๋ ํธ๋์ญ์ ์ ๊ฒฐ๊ณผ๊ฐ ์ค๋ ์ ์ฒด์ ํ์๋ ๋๊น์ง ๊ธฐ๋ค๋ฆด ํ์๋ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด, ํธ๋์ญ์ ์ด ์ปค๋ฐ๋๊ณ ์ฐ๊ธฐ 1์ด ์ค๋ A์ ํ์๋์ง๋ง ์ฐ๊ธฐ 2๊ฐ ์ค๋ B์ ์์ง ํ์๋์ง ์๋ ๊ฒฝ์ฐ, ์ฝ๊ธฐ ๊ณ ๋ ค
"local"
์ ์ธ๋ถ ์ฝ๊ธฐ๋ ์ฐ๊ธฐ 2๋ฅผ ๋ณด์ง ์๊ณ ์ฐ๊ธฐ 1์ ๊ฒฐ๊ณผ๋ฅผ ์ฝ์ ์ ์์ต๋๋ค.ํธ๋์ญ์ ์ด ์ค๋จ๋๋ฉด ํธ๋์ญ์ ์์ ๋ฐ์ํ ๋ชจ๋ ๋ฐ์ดํฐ ๋ณ๊ฒฝ ์ฌํญ์ ํ์๋์ง ์๊ณ ์ญ์ ๋ฉ๋๋ค. ์๋ฅผ ๋ค์ด, ํธ๋์ญ์ ์ ์์ ์ด ์คํจํ๋ฉด ํธ๋์ญ์ ์ด ์ค๋จ๋๊ณ ํธ๋์ญ์ ์ ๋ชจ๋ ๋ฐ์ดํฐ ๋ณ๊ฒฝ ์ฌํญ์ด ํ์๋์ง ์์ ์ฑ๋ก ํ๊ธฐ๋ฉ๋๋ค.
์ค์
๋๋ถ๋ถ์ ๊ฒฝ์ฐ ๋ถ์ฐ ํธ๋์ญ์ ์ ๋จ์ผ ๋ฌธ์ ์ฐ๊ธฐ์ ๋นํด ๋ ํฐ ์ฑ๋ฅ ๋น์ฉ์ด ๋ฐ์ํ๋ฏ๋ก ๋ถ์ฐ ํธ๋์ญ์ ์ ๊ฐ์ฉ์ฑ์ด ํจ๊ณผ์ ์ธ ์คํค๋ง ์ค๊ณ๋ฅผ ๋์ฒดํ ์๋ ์์ต๋๋ค. ๋๋ถ๋ถ์ ์๋๋ฆฌ์ค์์ ๋น์ ๊ทํ๋ ๋ฐ์ดํฐ ๋ชจ๋ธ (๋ด์ฅ๋ ๋ฌธ์ ๋ฐ ๋ฐฐ์ด) ์ ๊ณ์ํด์ ๋ฐ์ดํฐ ๋ฐ ์ฌ์ฉ ์ฌ๋ก์ ์ต์ ์ผ ๊ฒ์ ๋๋ค. ์ฆ, ๋๋ถ๋ถ์ ์๋๋ฆฌ์ค์์ ๋ฐ์ดํฐ๋ฅผ ์ ์ ํ๊ฒ ๋ชจ๋ธ๋งํ๋ฉด ๋ถ์ฐ ํธ๋์ญ์ ์ ํ์์ฑ์ด ์ต์ํ๋ฉ๋๋ค.
์ถ๊ฐ ํธ๋์ญ์ ์ฌ์ฉ ๊ณ ๋ ค ์ฌํญ(์: ๋ฐํ์ ์ ํ ๋ฐ oplog ํฌ๊ธฐ ์ ํ)์ ํ๋ก๋์ ๊ณ ๋ ค์ฌํญ์ ์ฐธ์กฐํ์ธ์.
ํธ๋์ญ์ ๋ฐ ์์
๋ถ์ฐ ํธ๋์ญ์ ์ ์ฌ๋ฌ ์์ , ์ปฌ๋ ์ , ๋ฐ์ดํฐ๋ฒ ์ด์ค, ๋ฌธ์ ๋ฐ ์ค๋ ์ ๋ฐ์ ๊ฑธ์ณ ์ฌ์ฉ๋ ์ ์์ต๋๋ค.
๊ฑฐ๋์ ๊ฒฝ์ฐ:
ํธ๋์ญ์ ๋ด์์ ์ปฌ๋ ์ ๊ณผ ์ธ๋ฑ์ค๋ฅผ ์์ฑํ ์ ์์ต๋๋ค. ์์ธํ ๋ด์ฉ์ ํธ๋์ญ์ ์์ ์ปฌ๋ ์ ๋ฐ ์ธ๋ฑ์ค ์์ฑํ๊ธฐ๋ฅผ ์ฐธ์กฐํ์ธ์.
ํธ๋์ญ์ ์ ์ฌ์ฉ๋๋ ์ปฌ๋ ์ ์ ์๋ก ๋ค๋ฅธ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์์ ์ ์์ต๋๋ค.
์ฐธ๊ณ
์ค๋ ๊ฐ ์ฐ๊ธฐ ํธ๋์ญ์ ์์๋ ์ ์ปฌ๋ ์ ์ ์์ฑํ ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด, ํ๋์ ์ค๋์์ ๊ธฐ์กด ์ปฌ๋ ์ ์ ์ฐ๊ณ ๋ค๋ฅธ ์ค๋์์ ์์์ ์ผ๋ก ์ ์ปฌ๋ ์ ์ ์์ฑํ๋ ๊ฒฝ์ฐ, MongoDB๋ ๋์ผํ ํธ๋์ญ์ ์์ ๋ ์์ ์ ๋ชจ๋ ์ํํ ์ ์์ต๋๋ค.
์ ํ๋ ์ปฌ๋ ์ ์๋ ์ธ (write) ์ ์์ต๋๋ค.
๊ณ ์ ์ฌ์ด์ฆ
์ปฌ๋ ์ ์์ ์ฝ์ ๋๋ ์ฝ๊ธฐ ๊ณ ๋ ค
"snapshot"
์ ์ฌ์ฉํ ์ ์์ต๋๋ค. (MongoDB 5.0๋ถํฐ ๋์ ๋จ)config
,admin
๋๋local
๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ปฌ๋ ์ ์ ์ฝ๊ณ ์ธ ์ ์์ต๋๋ค.system.*
์ปฌ๋ ์ ์ ์ธ ์ ์์ต๋๋ค.explain
๋๋ ์ด์ ์ ์ฌํ ๋ช ๋ น์ ์ฌ์ฉํ์ฌ ์ง์๋๋ ์์ ์ ์ฟผ๋ฆฌ ๊ณํ์ ๋ฐํํ ์ ์์ต๋๋ค.
ํธ๋์ญ์ ์ธ๋ถ์์ ์์ฑ๋ ์ปค์์ ๊ฒฝ์ฐ ํธ๋์ญ์ ๋ด๋ถ์์
getMore
์(๋ฅผ) ํธ์ถํ ์ ์์ต๋๋ค.ํธ๋์ญ์ ์์ ์์ฑ๋ ์ปค์์ ๊ฒฝ์ฐ ํธ๋์ญ์ ์ธ๋ถ์์
getMore
๋ฅผ ํธ์ถํ ์ ์์ต๋๋ค.
ํธ๋์ญ์
์ ์ฒซ ๋ฒ์งธ ์์ ์ผ๋ก
killCursors
๋ฅผ ์ง์ ํ ์ ์์ต๋๋ค.๋ํ ํธ๋์ญ์ ๋ด์์
killCursors
๋ช ๋ น์ ์คํ ํ๋ฉด ์๋ฒ ๊ฐ ์ง์ ๋ ์ปค์๋ฅผ ์ฆ์ ์ค์งํฉ๋๋ค. ํธ๋์ญ์ ์ด ์ปค๋ฐ ๋ ๋๊น์ง ๊ธฐ๋ค๋ฆฌ์ง ์์ต๋๋ค.
ํธ๋์ญ์ ์์ ์ง์๋์ง ์๋ ์์ ๋ชฉ๋ก์ ์ ํ๋ ์์ ์ ์ฐธ์กฐํ์ธ์.
ํ
ํธ๋์ญ์
์ ์์ํ๊ธฐ ์ง์ ์ ์ปฌ๋ ์
์ ๋ง๋ค๊ฑฐ๋ ์ ๊ฑฐํ ๋ ํธ๋์ญ์
๋ด์์ ์ปฌ๋ ์
์ ์ก์ธ์คํ๋ ๊ฒฝ์ฐ ์ฐ๊ธฐ ๊ณ ๋ ค "majority"
๊ฐ ์๋ ๋ง๋ค๊ธฐ ๋๋ ์ ๊ฑฐ ์์
์ ์คํํ์ฌ ํธ๋์ญ์
์ด ํ์ํ ์ ๊ธ์ ํ๋ํ ์ ์๋๋ก ํ์ธ์.
ํธ๋์ญ์ ์์ ์ปฌ๋ ์ ๋ฐ ์ธ๋ฑ์ค ์์ฑ
ํธ๋์ญ์ ์ด ๊ต์ฐจ ์ค๋ ์ฐ๊ธฐ ํธ๋์ญ์ (write transaction)์ด ์๋ ๊ฒฝ์ฐ ๋ถ์ฐ ํธ๋์ญ์ ์์ ๋ค์ ์์ ์ ์ํํ ์ ์์ต๋๋ค.
์ปฌ๋ ์ ์ ์์ฑํฉ๋๋ค.
๋์ผํ ํธ๋์ญ์ ์์ ์ด์ ์ ์์ฑ๋ ์๋ก์ด ๋น ์ปฌ๋ ์ ์ ์ธ๋ฑ์ค๋ฅผ ์์ฑ.
ํธ๋์ญ์ ๋ด์์ ์ปฌ๋ ์ ์ ๋ง๋ค ๋
๋ค์๊ณผ ๊ฐ์ด ์ปฌ๋ ์ ์ ์์์ ์ผ๋ก ๋ง๋ค ์ ์์ต๋๋ค.
์กด์ฌํ์ง ์๋ ์ปฌ๋ ์ ์ ๋ํ ์ฝ์ ์์ ๋๋
์กด์ฌํ์ง ์๋ ์ปฌ๋ ์ ์ ๋ํด
upsert: true
์(๋ฅผ) ์ฌ์ฉํ์ฌ ์ ๋ฐ์ดํธ/findAndModify ์์์ ์ํํฉ๋๋ค.
db.createCollection()
๋ช ๋ น ๋๋create
ํด๋น ๋์ฐ๋ฏธ ์ ์ฌ์ฉํ์ฌ ์ปฌ๋ ์ ์ ๋ช ์์ ์ผ๋ก ๋ง๋ค์ ์์ต๋๋ค.
ํธ๋์ญ์ ๋ด๋ถ์ ์ธ๋ฑ์ค๋ฅผ ์์ฑ ํ ๋ [1], ์์ฑํ ์ธ๋ฑ์ค๋ ๋ ์ค ํ๋์ ์์ด์ผ ํฉ๋๋ค.
์กด์ฌํ์ง ์๋ ์ปฌ๋ ์ ์ ๋๋ค. ์ปฌ๋ ์ ์ ์์ ์ ์ผ๋ถ๋ก ์์ฑ๋ฉ๋๋ค.
๋์ผํ ํธ๋์ญ์ ์์ ์ด์ ์ ์์ฑ๋ ์ ๋น ์ปฌ๋ ์ ์ ๋๋ค.
[1] | ๊ธฐ์กด ์ธ๋ฑ์ค์์ db.collection.createIndex() ๋ฐ db.collection.createIndexes() ๋ฅผ ์คํํ์ฌ ์กด์ฌ ์ฌ๋ถ๋ฅผ ํ์ธํ ์๋ ์์ต๋๋ค. ์ด๋ฌํ ์์
์ ์ธ๋ฑ์ค๋ฅผ ์์ฑํ์ง ์๊ณ ์ฑ๊ณต์ ์ผ๋ก ๋ฐํ๋ฉ๋๋ค. |
์ ํ ์ฌํญ
์ค๋ ๊ฐ ์ฐ๊ธฐ ํธ๋์ญ์ ์์๋ ์ ์ปฌ๋ ์ ์ ์์ฑํ ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด, ํ๋์ ์ค๋์์ ๊ธฐ์กด ์ปฌ๋ ์ ์ ์ฐ๊ณ ๋ค๋ฅธ ์ค๋์์ ์์์ ์ผ๋ก ์ ์ปฌ๋ ์ ์ ์์ฑํ๋ ๊ฒฝ์ฐ, MongoDB๋ ๋์ผํ ํธ๋์ญ์ ์์ ๋ ์์ ์ ๋ชจ๋ ์ํํ ์ ์์ต๋๋ค.
์ค๋ฉ๋ ์ปฌ๋ ์ ์ ๋์์ผ๋ก ํ๋ ๋์ ํธ๋์ญ์ ๋ด์์
$graphLookup
๋จ๊ณ๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค.
ํธ๋์ญ์ ๋ด์์ ์ปฌ๋ ์ ์ด๋ ์ธ๋ฑ์ค๋ฅผ ๋ช ์์ ์ผ๋ก ๋ง๋ค๋ ค๋ฉด ํธ๋์ญ์ ์ฝ๊ธฐ ๊ณ ๋ ค ์์ค์ด
"local"
์ฌ์ผ ํฉ๋๋ค.
์ปฌ๋ ์ ๋ฐ ์ธ๋ฑ์ค๋ฅผ ๋ช ์์ ์ผ๋ก ์์ฑํ๋ ค๋ฉด ๋ค์ ๋ช ๋ น๊ณผ ๋ฉ์๋๋ฅผ ์ฌ์ฉํฉ๋๋ค.
์นด์ดํธ ์ฐ์ฐ
ํธ๋์ญ์
๋ด์์ ์นด์ดํธ ์ฐ์ฐ์ ์ํํ๋ ค๋ฉด $count
์ง๊ณ ๋จ๊ณ ๋๋ $group
($sum
ํํ์ ํฌํจ) ์ง๊ณ ๋จ๊ณ๋ฅผ ์ฌ์ฉํฉ๋๋ค.
MongoDB ๋๋ผ์ด๋ฒ๋ $sum
ํํ์๊ณผ ํจ๊ป
$group
๋ฅผ ์ฌ์ฉํ์ฌ ์นด์ดํธ๋ฅผ ์ํํ๋ ํฌํผ ๋ฉ์๋๋ก์ ์ปฌ๋ ์
์์ค API countDocuments(filter, options)
์ ์ ๊ณตํฉ๋๋ค.
mongosh
๋ $sum
ํํ์๊ณผ ํจ๊ป $group
์ ์ฌ์ฉํ์ฌ ์นด์ดํธ๋ฅผ ์ํํ๋ ํฌํผ ๋ฉ์๋ db.collection.countDocuments()
๋ฅผ ์ ๊ณตํฉ๋๋ค.
์ฐจ๋ณํ๋ ์ด์
ํธ๋์ญ์ ๋ด์์ ๊ณ ์ ํ ์์ ์ ์ํํฉ๋๋ค.
์ค๋๋์ง ์์ ์ปฌ๋ ์ ์ ๊ฒฝ์ฐ,
db.collection.distinct()
๋ฉ์๋/distinct
๋ช ๋ น๊ณผ$group
๋จ๊ณ์ ์ง๊ณ ํ์ดํ๋ผ์ธ์ ์ฌ์ฉํ ์ ์์ต๋๋ค.๋ฆฌ์ค๋๋ ์ปฌ๋ ์ ์ ๊ฒฝ์ฐ
db.collection.distinct()
๋ฉ์๋ ๋๋distinct
๋ช ๋ น์ ์ฌ์ฉํ ์ ์์ต๋๋ค.์ค๋ฉ๋ ์ปฌ๋ ์ ์ ๊ณ ์ ๊ฐ์ ์ฐพ์ผ๋ ค๋ฉด ๋์
$group
๋จ๊ณ์ ์ง๊ณ ํ์ดํ๋ผ์ธ์ ์ฌ์ฉํฉ๋๋ค. ์์:{00}} ๋์ ๋ค์์ ์ฌ์ฉํฉ๋๋ค.
db.coll.aggregate([ { $group: { _id: null, distinctValues: { $addToSet: "$x" } } }, { $project: { _id: 0 } } ]) {00}} ๋์ ๋ค์์ ์ฌ์ฉํฉ๋๋ค.
db.coll.aggregate([ { $match: { status: "A" } }, { $group: { _id: null, distinctValues: { $addToSet: "$x" } } }, { $project: { _id: 0 } } ])
ํ์ดํ๋ผ์ธ์ ๋ฌธ์์ ์ปค์๋ฅผ ๋ฐํํฉ๋๋ค.
{ "distinctValues" : [ 2, 3, 1 ] } ์ปค์๋ฅผ ๋ฐ๋ณตํ์ฌ ๊ฒฐ๊ณผ ๋ฌธ์์ ์ก์ธ์คํฉ๋๋ค.
์ ๋ณด ์ด์
2} buildInfo
,hello
connectionStatus
, ๊ณผ ๊ฐ์ ์ ๋ณด ๋ช
๋ น(๋ฐ ๊ทธ ๋์ฐ๋ฏธ ๋ฉ์๋) (๋ฐ ํด๋น ํฌํผ ๋ฉ์๋)์ ๊ฐ์ ์ ๋ณด ๋ช
๋ น์ ํธ๋์ญ์
์์ ํ์ฉ๋์ง๋ง, ํธ๋์ญ์
์ ์ฒซ ๋ฒ์งธ ์ฐ์ฐ์ด ๋ ์๋ ์์ต๋๋ค.
์ ํ๋ ์์
ํธ๋์ญ์ ์์ ํ์ฉ๋์ง ์๋ ์์ ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
๋ค์ค ์ค๋ ์ฐ๊ธฐ ํธ๋์ญ์ ์์ ์๋ก์ด ์ปฌ๋ ์ ์ ์์ฑํ๊ธฐ. ์๋ฅผ ๋ค์ด ํ๋์ ์ค๋์์ ๊ธฐ์กด ์ปฌ๋ ์ ์ ์ฐ๊ณ ๋ค๋ฅธ ์ค๋์ ์์์ ์ผ๋ก ์ปฌ๋ ์ ์ ์์ฑํ๋ ๊ฒฝ์ฐ MongoDB๋ ๋์ผํ ํธ๋์ญ์ ์์ ๋ ์์ ์ ๋ชจ๋ ์ํํ ์ ์์ต๋๋ค.
์ปฌ๋ ์ (์:
db.createCollection()
๋ฉ์๋) ๋ฐ ์ธ๋ฑ์ค(์:db.collection.createIndexes()
๋ฐdb.collection.createIndex()
๋ฉ์๋)์ ์์ฑ์
"local"
์ด์ธ์ ์ฝ๊ธฐ ๊ณ ๋ ค ์์ค์ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ ๋ช ์ํฉ๋๋ค.
listCollections
2} ๋ฐ ๋ช ๋ น๊ณผ ํด๋น ๋์ฐ๋ฏธ ๋ฉ์๋.listIndexes
createUser
,getParameter
,count
๋ฑ๊ณผ ํด๋น ํฌํผ์ ๊ฐ์ ๊ธฐํ ๋น CRUD ๋ฐ ๋น ์ ๋ณด ์์ ์ ๋๋ค.๋ณ๋ ฌ ์์ . ์ฌ๋ฌ ๋ค์์คํ์ด์ค๋ฅผ ๋์์ ์ ๋ฐ์ดํธํ๋ ค๋ฉด
bulkWrite
๋ช ๋ น์ ์ฌ์ฉํ๋ ๊ฒ์ด ์ข์ต๋๋ค.
ํธ๋์ญ์ ๋ฐ ์ธ์
ํธ๋์ญ์ ์ ์ธ์ ๊ณผ ๊ด๋ จ์ด ์์ต๋๋ค.
์ธ์ ๋น ํ ๋ฒ์ ์ต๋ ํ ๊ฐ์ ์ด๋ฆฐ ํธ๋์ญ์ ๋ง ์งํํ ์ ์์ต๋๋ค.
๋๋ผ์ด๋ฒ๋ฅผ ์ฌ์ฉํ ๋ ํธ๋์ญ์ ์ ๊ฐ ์์ ์ ์ธ์ ๊ณผ ์ฐ๊ฒฐ๋์ด์ผ ํฉ๋๋ค. ์์ธํ ๋ด์ฉ์ ๋๋ผ์ด๋ฒ๋ณ ๋ฌธ์๋ฅผ ์ฐธ์กฐํ์ธ์.
์ธ์ ์ด ์ข ๋ฃ๋๊ณ ์ด๋ ค ์๋ ํธ๋์ญ์ ์ด ์๋ ๊ฒฝ์ฐ ํธ๋์ญ์ ์ด ์ค๋จ๋ฉ๋๋ค.
์ฝ๊ธฐ ๊ณ ๋ ค/์ฐ๊ธฐ ๊ณ ๋ ค/์ฝ๊ธฐ ์ค์
ํธ๋์ญ์ ๋ฐ ์ฝ๊ธฐ ํ๊ฒฝ์ค์
ํธ๋์ญ์ ์ ์์ ์๋ ํธ๋์ญ์ ์์ค ์ฝ๊ธฐ ๊ธฐ๋ณธ ์ค์ ์ด ์ฌ์ฉ๋ฉ๋๋ค.
๋๋ผ์ด๋ฒ๋ฅผ ์ฌ์ฉํ๋ฉด ํธ๋์ญ์ ์์ ์ ํธ๋์ญ์ ์์ค ์ฝ๊ธฐ ๊ธฐ๋ณธ ์ค์ ์ ์ง์ ํ ์ ์์ต๋๋ค.
ํธ๋์ญ์ ์์ค ์ฝ๊ธฐ ์ค์ ์ด ์ง์ ๋์ง ์์ ๊ฒฝ์ฐ ํธ๋์ญ์ ์ ์ธ์ ์์ค ์ฝ๊ธฐ ์ค์ ์ ์ฌ์ฉํฉ๋๋ค.
ํธ๋์ญ์ ์์ค ๋ฐ ์ธ์ ์์ค ์ฝ๊ธฐ ์ค์ ์ด ์ค์ ๋์ง ์์ ๊ฒฝ์ฐ ํธ๋์ญ์ ์ ํด๋ผ์ด์ธํธ ์์ค ์ฝ๊ธฐ ์ค์ ์ ์ฌ์ฉํฉ๋๋ค. ๊ธฐ๋ณธ์ ์ผ๋ก ํด๋ผ์ด์ธํธ ์์ค ์ฝ๊ธฐ ์ค์ ์
primary
์ ๋๋ค.
์ฝ๊ธฐ ์์
์ด ํฌํจ๋ ๋ถ์ฐ ํธ๋์ญ์
์ ์ฝ๊ธฐ ์ค์ primary
(์)๋ฅผ ์ฌ์ฉํด์ผ ํฉ๋๋ค. ํน์ ํธ๋์ญ์
์ ๋ชจ๋ ์์
์ ๋์ผํ ๊ตฌ์ฑ์์ผ๋ก ๋ผ์ฐํ
๋์ด์ผ ํฉ๋๋ค.
ํธ๋์ญ์ ๋ฐ ์ฝ๊ธฐ ์ฐ๋ ค
ํธ๋์ญ์ ์ ์์ ์ ํธ๋์ญ์ ์์ค ์ฝ๊ธฐ ๊ณ ๋ ค (read concern)๋ฅผ ์ฌ์ฉํฉ๋๋ค. ์ฆ, ์ปฌ๋ ์ ๋ฐ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์์ค์์ ์ค์ ๋ ์ฝ๊ธฐ ๊ณ ๋ ค (read concern)๋ ํธ๋์ญ์ ๋ด๋ถ์์ ๋ฌด์๋ฉ๋๋ค.
ํธ๋์ญ์ ์์ ์ ํธ๋์ญ์ ์์ค์ ์ฝ๊ธฐ ๋ฌธ์ ๋ฅผ ์ค์ ํ ์ ์์ต๋๋ค.
ํธ๋์ญ์ ์์ค ์ฝ๊ธฐ ๊ณ ๋ ค (read concern)๊ฐ ์ค์ ๋์ง ์์ ๊ฒฝ์ฐ ํธ๋์ญ์ ์์ค ์ฝ๊ธฐ ๊ณ ๋ ค๋ ๊ธฐ๋ณธ์ ์ผ๋ก ์ธ์ ์์ค ์ฝ๊ธฐ ๊ณ ๋ ค๋ก ์ค์ ๋ฉ๋๋ค.
ํธ๋์ญ์ ์์ค ๋ฐ ์ธ์ ์์ค ์ฝ๊ธฐ ๊ณ ๋ ค (read concern)๊ฐ ์ค์ ๋์ง ์์ ๊ฒฝ์ฐ, ํธ๋์ญ์ ์์ค ์ฝ๊ธฐ ๊ณ ๋ ค (read concern)๋ ๊ธฐ๋ณธ์ ์ผ๋ก ํด๋ผ์ด์ธํธ ์์ค ์ฝ๊ธฐ ๊ณ ๋ ค (read concern)๋ก ์ค์ ๋ฉ๋๋ค. ๊ธฐ๋ณธ์ ์ผ๋ก ํด๋ผ์ด์ธํธ ์์ค ์ฝ๊ธฐ ๊ณ ๋ ค (read concern)๋ ํ๋ผ์ด๋จธ๋ฆฌ ์ฝ๊ธฐ์์
"local"
์ ๋๋ค. ๋ค์๋ ์ฐธ์กฐํ์ธ์.
ํธ๋์ญ์ ์ ๋ค์๊ณผ ๊ฐ์ ์ฝ๊ธฐ ๊ณ ๋ ค ์์ค์ ์ง์ํฉ๋๋ค.
"local"
์ฝ๊ธฐ ๊ณ ๋ ค
"local"
๋ ๋ ธ๋์์ ์ฌ์ฉ ๊ฐ๋ฅํ ๊ฐ์ฅ ์ต๊ทผ ๋ฐ์ดํฐ๋ฅผ ๋ฐํํ์ง๋ง ๋กค๋ฐฑํ ์ ์์ต๋๋ค.๋ณต์ ๋ณธ ์ธํธ ์์๋ ํธ๋์ญ์ ์ด ์ฝ๊ธฐ ๊ณ ๋ ค (read concern)
local
์(๋ฅผ) ์ฌ์ฉํ๋๋ผ๋ ํธ๋์ญ์ ์ด ์ด๋ฆฐ ์ ์ ์ค๋ ์ท ์์ ์ฝ๋ ์์ ์์ ๋ ๊ฐ๋ ฅํ ์ฝ๊ธฐ ๊ฒฉ๋ฆฌ ๊ฐ ๊ด์ฐฐ๋ ์ ์์ต๋๋ค.ํธ๋์ญ์ ์ด ์ค๋ฉ๋ ํด๋ฌ์คํฐ์ ์๋ ๊ฒฝ์ฐ,
"local"
์ฝ๊ธฐ ๊ณ ๋ ค๋ ๋ฐ์ดํฐ๊ฐ ์ค๋ ์ ์ฒด์ ๋๋ฆฌํ ์ค๋ ์ท ๋ณด๊ธฐ์์ ๋์จ ๊ฒ์์ ๋ณด์ฅํ ์ ์์ต๋๋ค. ์ค๋ ์ท ๊ฒฉ๋ฆฌ๊ฐ ํ์ํ ๊ฒฝ์ฐ"snapshot"
์ฝ๊ธฐ ๊ณ ๋ ค๋ฅผ ์ฌ์ฉํ์ธ์.ํธ๋์ญ์ ๋ด์์ ์ปฌ๋ ์ ๊ณผ ์ธ๋ฑ์ค๋ฅผ ์์ฑํ ์ ์์ต๋๋ค. ์ปฌ๋ ์ ์ด๋ ์ธ๋ฑ์ค๋ฅผ ๋ช ์์ ์ผ๋ก ์์ฑํ๋ ๊ฒฝ์ฐ, ํธ๋์ญ์ ์ ๋ฐ๋์ ์ฝ๊ธฐ ๊ณ ๋ ค
"local"
(์)๋ฅผ ์ฌ์ฉํด์ผ ํฉ๋๋ค. ์ปฌ๋ ์ ์ ์์์ ์ผ๋ก ์์ฑํ๋ ๊ฒฝ์ฐ ์ฌ์ฉ ๊ฐ๋ฅํ ๋ชจ๋ ์ฝ๊ธฐ ๊ณ ๋ ค๋ฅผ ํธ๋์ญ์ ์ ์ฌ์ฉํ ์ ์์ต๋๋ค.
"majority"
ํธ๋์ญ์ ์ด ์ฐ๊ธฐ ๊ณ ๋ ค "majority"๋ก ์ปค๋ฐ๋๋ฉด ์ฝ๊ธฐ ๊ณ ๋ ค
"majority"
๋ ๋ณต์ ๋ณธ ์ธํธ ๋ฉค๋ฒ์ ๊ณผ๋ฐ์๊ฐ ์ธ์ ํ ๋ฐ์ดํฐ๋ฅผ ๋ฐํํ๋ฉฐ, ์ด๋ ๋กค๋ฐฑํ ์ ์์ต๋๋ค. ๊ทธ๋ ์ง ์์ผ๋ฉด ์ฝ๊ธฐ ๊ณ ๋ ค"majority"
๋ ์ฝ๊ธฐ ์์ ์ด ๊ณผ๋ฐ์๊ฐ ์ปค๋ฐ๋ ๋ฐ์ดํฐ๋ฅผ ์ฝ๋๋ค๋ ๋ณด์ฅ์ ์ ๊ณตํ์ง ์์ต๋๋ค.์ค๋ฉ๋ ํด๋ฌ์คํฐ์์์ ํธ๋์ญ์ ์ ๊ฒฝ์ฐ, ์ฝ๊ธฐ ๊ณ ๋ ค
"majority"
๋ ์ค๋ ์ ์ฒด์์ ๋์ผํ ์ค๋ ์ท ๋ทฐ์ ๋ฐ์ดํฐ์์ ๋ณด์ฅํ ์ ์์ต๋๋ค. ์ค๋ ์ท ๊ฒฉ๋ฆฌ๊ฐ ํ์ํ ๊ฒฝ์ฐ ์ฝ๊ธฐ ๊ณ ๋ ค"snapshot"
์ ์ฌ์ฉํ์ธ์.
"snapshot"
์ฝ๊ธฐ ๊ณ ๋ ค
"snapshot"
๋ ํธ๋์ญ์ ์ด ์ฐ๊ธฐ ๊ณ ๋ ค "majority"๋ก ์ปค๋ฐ๋ ๊ฒฝ์ฐ ๋๋ค์ ์ปค๋ฐ๋ ๋ฐ์ดํฐ์ ์ค๋ ์ท์์ ๋ฐ์ดํฐ๋ฅผ ๋ฐํํฉ๋๋ค.ํธ๋์ญ์ ์ด ์ปค๋ฐ์ ๋ํด ์ฐ๊ธฐ ๊ณ ๋ ค "majority"๋ฅผ ์ฌ์ฉํ์ง ์๋ ๊ฒฝ์ฐ,
"snapshot"
์ฝ๊ธฐ ๊ณ ๋ ค๋ ์ฝ๊ธฐ ์์ ์ด ๊ณผ๋ฐ์ ์ปค๋ฐ๋ ๋ฐ์ดํฐ์ ์ค๋ ์ท์ ์ฌ์ฉํ๋ค๋ ๋ณด์ฅ์ ์ ๊ณตํ์ง ์์ต๋๋ค.์ค๋ฉ๋ ํด๋ฌ์คํฐ์ ํธ๋์ญ์ ์ ๊ฒฝ์ฐ, ๋ฐ์ดํฐ์
"snapshot"
๋ณด๊ธฐ๊ฐ ์ค๋ ๊ฐ์ ๋๊ธฐํ๋ฉ๋๋ค.
ํธ๋์ญ์ ๋ฐ ์ฐ๊ธฐ ๊ณ ๋ ค
ํธ๋์ญ์ ์ ํธ๋์ญ์ ์์ค ์ฐ๊ธฐ ๊ณ ๋ ค (write concern)๋ฅผ ์ฌ์ฉํ์ฌ ์ฐ๊ธฐ (write) ์์ ์ ์ปค๋ฐํฉ๋๋ค. ํธ๋์ญ์ ๋ด๋ถ์ ์ฐ๊ธฐ (write) ์์ ์ ๋ช ์์ ์ธ ์ฐ๊ธฐ ๊ณ ๋ ค (write concern) ์ง์ ์์ด ์คํ๋์ด์ผ ํ๋ฉฐ ๊ธฐ๋ณธ๊ฐ ์ฐ๊ธฐ ๊ณ ๋ ค (write concern)๋ฅผ ์ฌ์ฉํด์ผ ํฉ๋๋ค. ์ปค๋ฐ ์ ํธ๋์ญ์ ์์ค ์ฐ๊ธฐ ๊ณ ๋ ค (write concern)๋ฅผ ์ฌ์ฉํ์ฌ ์ฐ๊ธฐ (write)๊ฐ ์ปค๋ฐ๋ฉ๋๋ค.
ํ
ํธ๋์ญ์ ๋ด๋ถ์ ๊ฐ๋ณ ์ฐ๊ธฐ (write) ์์ ์ ๋ํ ์ฐ๊ธฐ ๊ณ ๋ ค (write concern)๋ฅผ ๋ช ์์ ์ผ๋ก ์ค์ ํ์ง ๋ง์ธ์. ํธ๋์ญ์ ๋ด๋ถ์ ๊ฐ๋ณ ์ฐ๊ธฐ (write) ์์ ์ ๋ํ ์ฐ๊ธฐ ๊ณ ๋ ค (write concern)๋ฅผ ์ค์ ํ๋ฉด ์ค๋ฅ๊ฐ ๋ฐํ๋ฉ๋๋ค.
ํธ๋์ญ์ ์์ ์ ํธ๋์ญ์ ์์ค ์ฐ๊ธฐ ๋ฌธ์ ๋ฅผ ์ค์ ํ ์ ์์ต๋๋ค.
ํธ๋์ญ์ ์์ค ์ฐ๊ธฐ ๊ณ ๋ ค (write concern)๊ฐ ์ค์ ๋์ง ์์ ๊ฒฝ์ฐ, ํธ๋์ญ์ ์์ค ์ฐ๊ธฐ ๊ณ ๋ ค๋ ์ปค๋ฐ์ ๋ํ ์ธ์ ์์ค ์ฐ๊ธฐ ๊ณ ๋ ค๋ฅผ ๊ธฐ๋ณธ๊ฐ์ผ๋ก ์ฌ์ฉํฉ๋๋ค.
ํธ๋์ญ์ ์์ค ์ฐ๊ธฐ ๊ณ ๋ ค (write concern)์ ์ธ์ ์์ค ์ฐ๊ธฐ ๊ณ ๋ ค๊ฐ ์ค์ ๋์ง ์์ ๊ฒฝ์ฐ ํธ๋์ญ์ ์์ค ์ฐ๊ธฐ ๊ณ ๋ ค๋ ๊ธฐํด๋ผ์ด์ธํธ ์์ค ์ฐ๊ธฐ ๊ณ ๋ ค๋ฅผ ๊ธฐ๋ณธ๊ฐ์ผ๋ก ์ฌ์ฉํฉ๋๋ค.
MongoDB 5.0์
w: "majority"
๋ฐ ๊ทธ ์ด์์์๋ ์ค์ฌ์๊ฐ ํฌํจ๋ ๋ฐฐํฌ์ ๊ฒฝ์ฐ ์ฐจ์ด๊ฐ ์์ต๋๋ค. ์์์ ๊ธฐ๋ณธ ์ฐ๊ธฐ ๋ฌธ์ ๋ฅผ ์ฐธ์กฐํ์ธ์.
ํธ๋์ญ์ ์ ๋ค์์ ํฌํจํ ๋ชจ๋ ์ฐ๊ธฐ ๊ณ ๋ ค w ๊ฐ์ ์ง์ํฉ๋๋ค.
w: 1
์ฐ๊ธฐ ๊ณ ๋ ค
w: 1
์ ์ปค๋ฐ์ด ํ๋ผ์ด๋จธ๋ฆฌ์ ์ ์ฉ๋ ํ ์น์ธ์ ๋ฐํํฉ๋๋ค.์ค์
w: 1
๋ก ์ปค๋ฐํ ๋ ํ์ผ์ค๋ฒ๊ฐ ์๋ ๊ฒฝ์ฐ ํธ๋์ญ์ ์ ๋กค๋ฐฑํ ์ ์์ต๋๋ค.w: 1
์ฐ๊ธฐ ๊ณ ๋ ค๋ก"majority"
์ปค๋ฐํ๋ ๊ฒฝ์ฐ ํธ๋์ญ์ ์์ค ์ฝ๊ธฐ ๊ณ ๋ ค๋ ํธ๋์ญ์ ์ ์ฝ๊ธฐ ์์ ์ด ๋๋ค์ ์ปค๋ฐ๋ ๋ฐ์ดํฐ๋ฅผ ์ฝ์ง ์๋๋ค๋ ๋ณด์ฅ์ ์ ๊ณตํ์ง ์์ต๋๋ค.w: 1
์ฐ๊ธฐ ๊ณ ๋ ค๋ก ์ปค๋ฐํ๋ ๊ฒฝ์ฐ ํธ๋์ญ์ ์์ค"snapshot"
์ฝ๊ธฐ ๊ณ ๋ ค๋ ํธ๋์ญ์ ์ ์ฝ๊ธฐ ์์ ์ด ๋๋ค์ ์ปค๋ฐ๋ ๋ฐ์ดํฐ์ ์ค๋ ์ท์ ์ฌ์ฉํ๋ค๋ ๋ณด์ฅ์ ์ ๊ณตํ์ง ์์ต๋๋ค.
w: "majority"
์ฐ๊ธฐ ๊ณ ๋ ค
w: "majority"
๋ ํฌํ ๋ ธ๋ ๊ณผ๋ฐ์์๊ฒ ์ปค๋ฐ์ด ์ ์ฉ๋ ํ ์น์ธ์ ๋ฐํํฉ๋๋ค.w: "majority"
์ฐ๊ธฐ ๊ณ ๋ ค๋ก ์ปค๋ฐํ๋ ๊ฒฝ์ฐ ํธ๋์ญ์ ์์ค"majority"
์ฝ๊ธฐ ๊ณ ๋ ค๋ ์์ ์ด ๋๋ค์ ์ปค๋ฐ๋ ๋ฐ์ดํฐ๋ฅผ ์ฝ์์์ ๋ณด์ฅํฉ๋๋ค. ์ค๋ฉ๋ ํด๋ฌ์คํฐ์ ํธ๋์ญ์ ์ ๊ฒฝ์ฐ ๋๋ถ๋ถ ์ปค๋ฐ๋ ๋ฐ์ดํฐ์ ๋ํ ์ด ๋ณด๊ธฐ๋ ์ค๋ ์ ์ฒด์์ ๋๊ธฐํ๋์ง ์์ต๋๋ค.w: "majority"
2} ์ฐ๊ธฐ ๊ณ ๋ ค๋ก ์ปค๋ฐํ ๋ ํธ๋์ญ์ ์์ค"snapshot"
์ฝ๊ธฐ ๊ณ ๋ ค๋ ์์ ์ด ๋๋ค์ ์ปค๋ฐ๋ ๋ฐ์ดํฐ์ ๋๊ธฐํ๋ ์ค๋ ์ท์์ ์ฝ์ ๊ฒ์ ๋ณด์ฅํฉ๋๋ค.
์ฐธ๊ณ
ํธ๋์ญ์
์ ์ง์ ๋ ์ฐ๊ธฐ ๊ณ ๋ ค์ ๊ด๊ณ์์ด, ์ค๋ฉ๋ ํด๋ฌ์คํฐ ํธ๋์ญ์
์ ๋ํ ์ปค๋ฐ ์์
์๋ {w:
"majority", j: true}
์ฐ๊ธฐ ๊ณ ๋ ค๋ฅผ ์ฌ์ฉํ๋ ์ผ๋ถ ๋ถ๋ถ์ด ํฌํจ๋ฉ๋๋ค.
์๋ฒ ๋งค๊ฐ๋ณ์ coordinateCommitReturnImmediatelyAfterPersistingDecision
๋ ํธ๋์ญ์
์ปค๋ฐ ๊ฒฐ์ ์ด ํด๋ผ์ด์ธํธ์ ๋ฐํ๋๋ ์๊ธฐ๋ฅผ ์ ์ดํฉ๋๋ค.
์ด ๋งค๊ฐ ๋ณ์๋ MongDB 5.0์์ ๊ธฐ๋ณธ๊ฐ์ด true
๋ก ๋์
๋์์ต๋๋ค. MongoDB 6.1์์๋ ๊ธฐ๋ณธ๊ฐ์ด false
๋ก ๋ณ๊ฒฝ๋ฉ๋๋ค.
coordinateCommitReturnImmediatelyAfterPersistingDecision
์ด false
๊ฐ ๋๋ฉด ์ค๋ ํธ๋์ญ์
์ฝ๋๋ค์ดํฐ๋ ๋ชจ๋ ๋ฉค๋ฒ๊ฐ ๋ค์ค ๋ฌธ์ ํธ๋์ญ์
์ปค๋ฐ์ ์น์ธํ ๋๊น์ง ๊ธฐ๋ค๋ฆฐ ๋ค์ ์ปค๋ฐ ๊ฒฐ์ ์ ํด๋ผ์ด์ธํธ์ ๋ฐํํฉ๋๋ค.
"majority"
๋จ์ผ ๋ฌธ์ ๋ฐ ๋ค์ค ๋ฌธ์ ์ฐ๊ธฐ์ ์ฐ๊ธฐ ๊ณ ๋ ค (write concern) ์ง์ ํ๊ณ ์์
์ด ์๋ต์ ๋ฐํํ๊ธฐ ์ ์ ๊ณ์ฐ๋ ๊ณผ๋ฐ์ ์ด์์ ๋ณต์ ๋ณธ ์ธํธ ๋ฉค๋ฒ์ ๋ณต์ ํ์ง ์์ผ๋ฉด ๋ฐ์ดํฐ๊ฐ ๊ฒฐ๊ตญ ๋ณต์ ๋๊ฑฐ๋ ๋กค๋ฐฑ๋ฉ๋๋ค. ๋ฅผ wtimeout
์ฐธ์กฐํ์ธ์.
ํธ๋์ญ์
์ ์ง์ ๋ ์ฐ๊ธฐ ๊ณ ๋ ค์ ๊ด๊ณ์์ด ๋๋ผ์ด๋ฒ๋ commitTransaction
(์)๋ฅผ ์ฌ์๋ํ ๋ ์ฐ๊ธฐ ๊ณ ๋ ค๋ก
w: "majority"
(์)๋ฅผ ์ ์ฉํฉ๋๋ค
์ผ๋ฐ ์ ๋ณด
๋ค์ ์น์ ์์๋ ํธ๋์ญ์ ์ ๋ํ ์ถ๊ฐ ๊ณ ๋ ค ์ฌํญ์ ์ค๋ช ํฉ๋๋ค.
ํ๋ก๋์ ๊ณ ๋ ค ์ฌํญ
ํ๋ก๋์ ํ๊ฒฝ์์์ ํธ๋์ญ์ ์ ๋ํด์๋ ํ๋ก๋์ ๊ณ ๋ ค ์ฌํญ์ ์ฐธ์กฐํ์ธ์. ๋ํ ์ค๋ฉ๋ ํด๋ฌ์คํฐ์ ๊ฒฝ์ฐ ํ๋ก๋์ ๊ณ ๋ ค ์ฌํญ(์ค๋ฉ๋ ํด๋ฌ์คํฐ)์ ์ฐธ์กฐํ์ธ์.
์ค์ฌ์
๋ณต์ ๋ณธ ์ธํธ ์ ์ค์ฌ์ ๊ฐ ์๋ ๊ฒฝ์ฐ ํธ๋์ญ์ ์ ์ฌ์ฉํ์ฌ ์ค๋ ํค ๋ฅผ ๋ณ๊ฒฝํ ์ ์์ต๋๋ค. ์ค์ฌ์๋ ๋ฉํฐ ์ค๋ ํธ๋์ญ์ ์ ํ์ํ ๋ฐ์ดํฐ ์์ ์ ์ฐธ์ฌํ ์ ์์ต๋๋ค.
์ฐ๊ธฐ ์์ ์ด ์ฌ๋ฌ ์ค๋์ ๊ฑธ์ณ ์๋ ํธ๋์ญ์ ์ ํธ๋์ญ์ ์์ ์ค ์ด๋ค ๊ฒ์ด๋ ์ค์ฌ์๊ฐ ํฌํจ๋ ์ค๋์์ ์ฝ๊ฑฐ๋ ์ฐ๋ ๊ฒฝ์ฐ ์ค๋ฅ๋ฅผ ๋ฐ์์ํค๊ณ ์ค๋จ๋ฉ๋๋ค.
์ค๋ ๊ตฌ์ฑ ์ ํ
writeConcernMajorityJournalDefault
๊ฐ false
๋ก ์ค์ ๋ ์ค๋๊ฐ ์๋ ์ค๋ฉ๋ ํด๋ฌ์คํฐ์์๋ ํธ๋์ญ์
์ ์คํํ ์ ์์ต๋๋ค. (์: ์ธ๋ฉ๋ชจ๋ฆฌ ์คํ ๋ฆฌ์ง ์์ง์ ์ฌ์ฉํ๋ ํฌํ ๋ฉค๋ฒ๊ฐ ์๋ ์ค๋)
์ฐธ๊ณ
ํธ๋์ญ์
์ ์ง์ ๋ ์ฐ๊ธฐ ๊ณ ๋ ค์ ๊ด๊ณ์์ด, ์ค๋ฉ๋ ํด๋ฌ์คํฐ ํธ๋์ญ์
์ ๋ํ ์ปค๋ฐ ์์
์๋ {w:
"majority", j: true}
์ฐ๊ธฐ ๊ณ ๋ ค๋ฅผ ์ฌ์ฉํ๋ ์ผ๋ถ ๋ถ๋ถ์ด ํฌํจ๋ฉ๋๋ค.
์ง๋จ
ํธ๋์ญ์ ์ํ ๋ฐ ์งํ๋ฅผ ์ป์ผ๋ ค๋ฉด ๋ค์ ๋ฉ์๋๋ฅผ ์ฌ์ฉํ์ธ์.
์์ค | ๋ฐํ |
---|---|
db.serverStatus() methodserverStatus command | ํธ๋์ญ์ ์ธก์ ํญ๋ชฉ์ ๋ฐํํฉ๋๋ค. Some |
| ๋ฐํํฉ๋๋ค:
|
db.currentOp() methodcurrentOp command | ๋ฐํํฉ๋๋ค:
|
|
๊ธฐ๋ฅ ํธํ ๋ฒ์ (fCV)
ํธ๋์ญ์ ์ ์ฌ์ฉํ๋ ค๋ฉด ๋ํ๋ก์ด๋จผํธ์ ๋ชจ๋ ๋ฉค๋ฒ์ ๋ํ FeatureCompatibilityVersion์ด ์ต์ํ ๋ค์๊ณผ ๊ฐ์์ผ ํฉ๋๋ค.
๋ฐฐํฌ | ์ต์ featureCompatibilityVersion |
---|---|
๋ณต์ ๋ณธ ์ธํธ |
|
์ค๋ฉ๋ ํด๋ฌ์คํฐ |
|
๋ฉค๋ฒ์ fCV๋ฅผ ํ์ธํ๋ ค๋ฉด ํด๋น ๋ฉค๋ฒ์ ์ฐ๊ฒฐํ๊ณ ๋ค์ ๋ช ๋ น์ ์คํํ์ธ์.
db.adminCommand( { getParameter: 1, featureCompatibilityVersion: 1 } )
์์ธํ ๋ด์ฉ์ setFeatureCompatibilityVersion
๋์๋ง ํ์ด์ง๋ฅผ ์ฐธ์กฐํ์ธ์.
์คํ ๋ฆฌ์ง ์์ง
๋ณต์ ๋ณธ ์ธํธ์ ์ค๋ฉ๋ ํด๋ฌ์คํฐ์์ ์ง์๋๋ ๋ถ์ฐ ํธ๋์ญ์ ์ ๋ค์ ์กฐ๊ฑด์์ ์ฌ์ฉํ ์ ์์ต๋๋ค.
ํ๋ผ์ด๋จธ๋ฆฌ๋ WiredTiger ์คํ ๋ฆฌ์ง ์์ง์ ์ฌ์ฉํฉ๋๋ค.
๋ณด์กฐ ๋ฉค๋ฒ๋ ์์ด์ด๋ํ์ด๊ฑฐ ์คํ ๋ฆฌ์ง ์์ง ๋๋ ์ธ๋ฉ๋ชจ๋ฆฌ ์คํ ๋ฆฌ์ง ์์ง์ ์ฌ์ฉํฉ๋๋ค.
์ฐธ๊ณ
writeConcernMajorityJournalDefault
๊ฐ false
์ผ๋ก ์ค์ ๋ ์ค๋๊ฐ ์๋ ์ค๋ ํด๋ฌ์คํฐ (์: ์ธ๋ฉ๋ชจ๋ฆฌ ์คํ ๋ฆฌ์ง ์์ง์ ์ฌ์ฉํ๋ ํฌํ ๋ฉค๋ฒ๊ฐ ์๋ ์ค๋)์์๋ ํธ๋์ญ์
์ ์คํํ ์ ์์ต๋๋ค.
์ค์ ๊ตฌ๊ฐ ๋๊ธฐ ์๊ฐ ์ ํ
MongoDB 5.2(๋ฐ 5.0.4)๋ถํฐ ์์๋ฉ๋๋ค.
์ฟผ๋ฆฌ๊ฐ ๋ถํ ๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ก์ธ์คํ ๋ ์ฒญํฌ ๋ง์ด๊ทธ๋ ์ด์ ๋๋ DDL ์์ ์ ์ปฌ๋ ์ ์ ๋ํ ์ค์ํ ์น์ ์ ๋ณด์ ํ ์ ์์ต๋๋ค.
์ค๋๊ฐ ํธ๋์ญ์ ๋ด ์ค์ ์น์ ๊น์ง ๋๊ธฐํ๋ ์๊ฐ์ ์ ํํ๋ ค๋ฉด
metadataRefreshInTransactionMaxWaitBehindCritSecMS
๋งค๊ฐ๋ณ์๋ฅผ ์ฌ์ฉํ์ธ์.