[MongoDB] Lock

MongoDB๋„ ์—ฌํƒ€ DB๋“ค๊ณผ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ๋™์‹œ์„ฑ ์ œ์–ด๋ฅผ ์œ„ํ•œ Lock ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•œ๋‹ค.



Lock mode

MongoDB๋Š” ํฌ๊ฒŒ 2๊ฐ€์ง€์˜ Lock ๋งค์ปค๋‹ˆ์ฆ˜์„ ์ง€์›ํ•œ๋‹ค.


  1. Shared Lock: lock์„ ์ ์œ ํ•œ ๋ฐ์ดํ„ฐ๋Š” ๋‹ค๋ฅธ write๊ฐ€ ๋“ค์–ด์˜ฌ ์ˆ˜ ์—†๋‹ค. ํ•˜์ง€๋งŒ ์—ฌ๋Ÿฌ๊ฐœ์˜ read๋Š” ํ—ˆ์šฉํ•œ๋‹ค.(RWLock)

  2. Exclusive Lock: lock์„ ์ ์œ ํ•œ ๋ฐ์ดํ„ฐ๋Š” ๋‹ค๋ฅธ read/write๊ฐ€ ์ „๋ถ€ ๋“ค์–ด์˜ฌ ์ˆ˜ ์—†๋‹ค.



์„ธ๋ถ„ํ™”ํ•˜๋ฉด Intent.. ์–ด์ฉŒ๊ณ  ํ•˜๋Š”๊ฒŒ ๋” ์žˆ๊ธด ํ•œ๋ฐ, ๊ธฐ๋ณธ์ ์ธ ์›๋ฆฌ๋Š” ์—ฌ๊ธฐ์—์„œ ๋ฒ—์–ด๋‚˜์ง€ ์•Š๋Š”๋‹ค.

๊ทธ๋ฆฌ๊ณ  ๊ฐ ์—ฐ์‚ฐ์˜ ๊ธฐ๋ณธ Lock ๋™์ž‘์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค. r์ด Shared Lock์ด๊ณ , w๊ฐ€ Exclusive Lock์ด๋‹ค.

https://www.mongodb.com/docs/manual/faq/concurrency/
๋Œ€๋ถ€๋ถ„์˜ mutable ์—ฐ์‚ฐ์ด Exclusive Lock์ด๊ณ  readonly ์—ฐ์‚ฐ์ด Shared Lock์ž„์„ ์•Œ ์ˆ˜ ์žˆ๋‹ค.

์ด๋Ÿฌํ•œ Lock ๊ธฐ๋Šฅ์„ ํ†ตํ•ด MongoDB๋Š” document ๋‹จ์œ„์˜ atomic์„ ๋ณด์žฅํ•œ๋‹ค.




Lock ์ถฉ๋Œ์‹œ์˜ ๋™์ž‘

๋™์‹œ์— ์—ฌ๋Ÿฌ๊ฐœ์˜ operation๋“ค์„ ์ˆ˜ํ–‰ํ•˜๋‹ค๋ณด๋ฉด, Lock์ด ์ด๋ฏธ ๊ฑธ๋ฆฐ ์ƒํƒœ์—์„œ ๋˜๋‹ค๋ฅธ write operation์ด ๋“ค์–ด์˜ฌ ๊ฒฝ์šฐ๊ฐ€ ๋งŽ์„ ๊ฒƒ์ด๋‹ค.
์ด๋Ÿด ๋•Œ ๊ธฐ์กด์˜ RDB๋“ค์€ Lock์ด ํ’€๋ฆด๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ ธ๋‹ค๊ฐ€ Lock์ด ํ’€๋ฆฌ๋ฉด ๋งˆ์ € ์ฒ˜๋ฆฌ๋ฅผ ํ•˜๋Š” ๋ฐฉ์‹์„ ์ทจํ•˜๋Š”๋ฐ, MongoDB์˜ ํ•ด๊ฒฐ๋ฐฉ์‹์€ ๊ฝค ๋…ํŠนํ•˜๋‹ค.

https://rastalion.me/mongodb-transaction-management/
์ด๋ฏธ Lock์ด ๊ฑธ๋ ค์žˆ๋Š” ๋ฐ์ดํ„ฐ์— write๋ฅผ ์‹œ๋„ํ•˜๋ฉด, ๋ชฝ๊ณ  ์„œ๋ฒ„๋Š” ๊ทธ์— ๋Œ€ํ•ด ์—๋Ÿฌ๋ฅผ ๋˜์ง„๋‹ค.
๊ทธ๋ฆฌ๊ณ  ์—๋Ÿฌ๊ฐ€ ๋‚˜๋ฉด ๋‹ค์‹œ ์‹œ๋„ํ•˜๊ณ , ๋‹ค์‹œ ์‹œ๋„ํ•˜๊ณ ... ์˜ ๋ฐฉ๋ฒ•์„ ๊ณ„์† ์‚ฌ์šฉํ•œ๋‹ค.

MongoDB ๋‚ด๋ถ€์—์„œ๋งŒ ์ผ์–ด๋‚˜๋Š” ์ผ์ด๋ผ ์‚ฌ์šฉ์— ํฐ ๋ถˆํŽธํ•จ์€ ์—†์ง€๋งŒ, ์ด๊ฒŒ ๋„ˆ๋ฌด ๋Š˜์–ด๋‚˜๋ฉด ์„ฑ๋Šฅ์— ์ง€์žฅ์„ ์ฃผ๊ฒŒ ๋œ๋‹ค.
CPU ์‚ฌ์šฉ๋Ÿ‰๋„ ๋งค์šฐ ์ปค์ง€๊ณ , ๋‚ด๋ถ€์˜ WiredTiger ์บ์‹œ์—๋„ ๋ถ€๋‹ด์„ ์ค˜์„œ ์ „์ฒด์ ์ธ ์„ฑ๋Šฅ์„ ์ €ํ•˜์‹œํ‚ค๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค...




multi-document transaction

์ด๊ฒŒ ๋ญ๋ƒ๋ฉด, RDB์—์„œ ์“ฐ๋˜ ๊ทธ ์ˆ˜๋™ ํŠธ๋žœ์žญ์…˜ ๊ธฐ๋Šฅ์„ ๋งํ•œ๋‹ค.
์—ฌ๋Ÿฌ๊ฐœ์˜ operation์„ ํ•˜๋‚˜๋กœ ๋ฌถ์–ด์„œ ํ•˜๋‚˜์˜ Lock ๋‹จ์œ„๋กœ ์ฒ˜๋ฆฌํ•˜๋Š” ๊ฒƒ์ด๋‹ค.

MongoDB๋Š” NoSQL์ด๋ฉด์„œ๋„ RDB์˜ ์˜์—ญ๊นŒ์ง€ ๋…ธ๋ฆฌ๋Š” ์• ๋งคํ•œ ๋…€์„์ด๋ผ์„œ, ์ด๋Ÿฐ๊ฒƒ๋„ ๋น„์Šทํ•˜๊ฒŒ ์ง€์›ํ•œ๋‹ค...

๋ฆฌ์†Œ์Šค๋ฅผ ๋Œ€๋‹จํžˆ ๋งŽ์ด ๋จน์„ ์ˆ˜ ์žˆ๋Š” ๊ธฐ๋Šฅ์ด๋ผ ๊ถŒ์žฅ๋˜์ง€๋Š” ์•Š๋Š”๋‹ค.

์‚ฌ์ „ ์กฐ๊ฑด์ด ํ•˜๋‚˜ ์žˆ๋‹ค. MongoDB ์„œ๋ฒ„๊ฐ€ ๋ฌด์กฐ๊ฑด ๋‹จ์ผ ์ธ์Šคํ„ด์Šค๊ฐ€ ์•„๋‹ˆ๋ผ replicaset ๋ชจ๋“œ์—ฌ์•ผ ํ•œ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค.
๊ทผ๋ฐ ๋ ˆํ”Œ๋ฆฌ์นด์ธ๊ฑฐ๋ž‘ ํŠธ๋žœ์žญ์…˜ ์ž‘๋™์—ฌ๋ถ€๊ฐ€ ๋Œ€์ฒด ๋ฌด์Šจ ์ƒ๊ด€์ด์ง€...? ์ด๊ฑด ๋ชฝ๊ณ  ๊ฐœ๋ฐœ์ž๋“ค ์‹ค์ˆ˜์ธ๊ฑฐ๊ฐ™๋‹ค.

์•„๋ž˜๋Š” Node.js ๊ธฐ๋ฐ˜์˜ ๊ฐ„๋‹จํ•œ transaction ์‚ฌ์šฉ ์˜ˆ์ œ๋‹ค.

const { MongoClient } = require("mongodb");

const url =
  "mongodb://127.0.0.1:27017/?directConnection=true&serverSelectionTimeoutMS=2000&appName=mongosh+1.6.0&replicaSet=rs0";
const client = new MongoClient(url);

async function main() {
  await client.connect();

  // ์„ธ์…˜ ์‹œ์ž‘
  const session = client.startSession();

  // ํŠธ๋žœ์žญ์…˜ ์˜ต์…˜ ์„ค์ •
  const transactionOptions = {
    readPreference: "primary",
    readConcern: { level: "local" },
    writeConcern: { w: "majority" },
  };

  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();
  }
}

main();



์ฐธ์กฐ
https://rastalion.me/mongodb-lock-%EC%9E%A0%EA%B8%88/
https://www.mongodb.com/docs/manual/core/write-operations-atomicity/
https://www.mongodb.com/docs/manual/core/transactions/
https://stackoverflow.com/questions/51461952/mongodb-v4-0-transaction-mongoerror-transaction-numbers-are-only-allowed-on-a
https://www.mongodb.com/docs/manual/core/write-operations-atomicity/