Transaction isolation level ও যে bug সেগুলো ঠেকায়

Isolation ঠিক করে একটি transaction অন্যটির কতটা দেখতে পায়। চার level এবং এর পেছনের concurrency bug জানুন।

মাঝে দেয়ালসহ দুটি overlapping transaction

অনেক transaction একসাথে চললে তারা একে অপরের অর্ধেক-শেষ কাজ দেখতে পারে। Isolation level ঠিক করে কতটা। শক্ত isolation মানে কম বিস্ময়, কিন্তু সাধারণত বেশি অপেক্ষা বা retry।

Anomaly

  • Dirty read: অন্য transaction বদলেছে কিন্তু commit করেনি এমন data পড়া। সে rollback করলে আপনি এমন data দেখেছেন যা কখনো ছিলই না।
  • Non-repeatable read: একই transaction-এ একটি row দুবার পড়ে ভিন্ন মান পাওয়া, কারণ দুই পড়ার মাঝে কেউ পরিবর্তন commit করেছে।
  • Phantom read: একই query দুবার চালিয়ে row-এর সেট বদলে যাওয়া, কারণ কেউ মিলে যাওয়া row insert বা delete করেছে।
  • Lost update: দুই transaction একই মান পড়ে, দুজনেই বদলায়, আর একজন অন্যটিকে overwrite করে।
  • Write skew: দুই transaction overlapping data পড়ে, তার ভিত্তিতে সিদ্ধান্ত নেয় এবং আলাদা row লেখে, একসাথে একটি নিয়ম ভাঙে। উদাহরণ: দুজন ডাক্তারই on-call ছাড়েন, কারণ প্রত্যেকে দেখেছিলেন অন্যজন এখনও on-call।

চার আদর্শ level

Level Dirty read Non-repeatable read Phantom
Read uncommitted সম্ভব সম্ভব সম্ভব
Read committed ঠেকানো সম্ভব সম্ভব
Repeatable read ঠেকানো ঠেকানো সম্ভব (আদর্শ অনুযায়ী)
Serializable ঠেকানো ঠেকানো ঠেকানো

আসল database পাঠ্যবইয়ের টেবিল থেকে আলাদা। যেমন PostgreSQL-এর repeatable read snapshot দিয়ে phantom-ও ঠেকায়, কিন্তু write skew ঘটতে দেয়।

সাধারণ ডিফল্ট

  • PostgreSQL: read committed।
  • MySQL (InnoDB): repeatable read।
  • SQLite: কার্যত ক্রমিক write, একবারে একজন writer।

নিজের database-এর ডকুমেন্টেশন দেখুন, কারণ আচরণ হুবহু এক নয়।

Database কীভাবে করে

দুটি প্রধান কৌশল:

  • Locking: reader ও writer একে অপরের জন্য অপেক্ষা করে।
  • MVCC (multi-version concurrency control): প্রতিটি transaction একটি snapshot দেখে, তাই reader writer-কে আটকায় না। PostgreSQL ও MySQL InnoDB এটি ব্যবহার করে।

কোন level ব্যবহার করবেন

  • বেশিরভাগ ওয়েব অ্যাপের জন্য read committed ভালো ডিফল্ট।
  • Balance, inventory ও scheduling-এর মতো যেখানে সিদ্ধান্ত পড়া data-র ওপর নির্ভর করে, সেখানে repeatable read বা serializable। Serializable serialisation error দিয়ে transaction বাতিল করতে পারে, তাই retry-র জন্য প্রস্তুত থাকুন।
  • ভুল data সত্যিই মেনে নিলে ছাড়া read uncommitted বাছবেন না।

সঠিকতার অন্য টুল

  • যে row বদলাবেন তা lock করতে SELECT ... FOR UPDATE।
  • version column দিয়ে optimistic locking: version এখনও মিললেই আপডেট।
  • Atomic update: read-তারপর-write-এর বদলে UPDATE stock SET qty = qty - 1 WHERE qty > 0।
  • ডুপ্লিকেট ঠেকাতে unique constraint।

মূল কথা: আপনার ডিফল্ট level জানুন, সিদ্ধান্ত পড়ার ওপর নির্ভর করলে শক্ত isolation বা স্পষ্ট lock ব্যবহার করুন, এবং সবসময় retry-র জন্য প্রস্তুত থাকুন।


Backend ও Database সিরিজ, পর্ব ১ (SQL ও transaction): 4 নম্বর (মোট 4)। আগের লেখা: Database transaction ও ACID সহজ ভাষায়.

আরও পড়ুন

Recursion ও backtracking সহজ উদাহরণে

Recursion সমস্যার ছোট কপি সমাধান করে সমাধান করে। অনেক interview সমস্যায় ব্যবহৃত চিন্তার ধাপ ও backtracking টেমপ্লেট শিখুন।

Interview ও DSA•৩ মিনিটে পড়া