একজন ডেভেলপার গাইড সতর্ক করেছে যে, একটি AI-চালিত চ্যাটের পুরো সময় জুড়ে একটি ডাটাবেস ট্রানজ্যাকশন (database transaction) খোলা রাখলে উত্তরগুলো ভুল বা ত্রুটিপূর্ণ হতে পারে এবং এর ফলে মূল DBMS-এর ওপর অতিরিক্ত চাপ সৃষ্টি হতে পারে। LLM-ভিত্তিক টুল তৈরি করা দলগুলোর উদ্দেশ্যে লেখা এই নোটে বলা হয়েছে যে, এই পদ্ধতিটি "অনুসরণ করা উচিত নয়" এবং এর পরিবর্তে চারটি স্বল্পস্থায়ী কনসিস্টেন্সি প্যাটার্ন ব্যবহারের পরামর্শ দেওয়া হয়েছে।

কেন এই সতর্কতাটি গুরুত্বপূর্ণ

LLM-চালিত অ্যাসিস্ট্যান্টরা প্রায়ই ধারাবাহিকভাবে কিছু ফলো-আপ প্রশ্ন করে: তারা একটি রেকর্ড পড়ে, একটি বিস্তারিত তথ্য অনুরোধ করে, তারপর একটি সমষ্টি বা টোটাল জানতে চায়। যদি সেই ধাপগুলোর মাঝখানে মূল ডেটা পরিবর্তিত হয়ে যায়, তবে অ্যাসিস্ট্যান্ট পরস্পরবিরোধী তথ্য প্রদান করতে পারে—যার ফলে একটি উত্তর ভুল হবে। এর একটি সহজ সমাধান মনে হতে পারে কথোপকথনের শুরুতে একটি মাত্র ট্রানজ্যাকশন খোলা রাখা এবং চ্যাট শেষ না হওয়া পর্যন্ত তা চালু রাখা। বাস্তবে, এই পদ্ধতিটি রো ভার্সনগুলোকে (row versions) আটকে রাখে, tempdb পূর্ণ করে ফেলে, লক (locks) ধরে রাখে এবং কানেকশন পুলিংয়ে বাধা সৃষ্টি করে।

দীর্ঘস্থায়ী ট্রানজ্যাকশনের কারণসমূহ

  • মাল্টি-টার্ন প্রম্পটিং (Multi-turn prompting) – ব্যবহারকারী কোনো রেসপন্স দেখার আগেই LLM সাধারণত বেশ কয়েকটি প্রম্পট তৈরি করে।
  • ডাটাবেসে টুলের কল (Tool calls that hit the database) – প্রতিটি টার্নে একটি স্টোরড প্রসিডিউর (stored procedure), একটি SELECT, অথবা একটি UPDATE কল হতে পারে।
  • অনিয়ন্ত্রিত ট্রানজ্যাকশন স্কোপ (Uncontrolled transaction scope) – ডেভেলপাররা অনেক সময় পুরো চ্যাটটিকে একটি BEGIN…COMMIT ব্লকের মধ্যে রাখেন এই আশায় যে এটি কনসিস্টেন্সি (consistency) নিশ্চিত করবে।

যখন চ্যাট দীর্ঘায়িত হয়, তখন ডাটাবেস ইঞ্জিনকে মূল রো ভার্সনগুলো ধরে রাখতে হয় যাতে ট্রানজ্যাকশনটি একটি স্থিতিশীল ভিউ (stable view) দেখতে পায়। এই ভার্সনগুলো tempdb-তে জমা হয়, যা স্পেস এবং I/O খরচ করে। একই সময়ের জন্য ধরে রাখা লকগুলো সমসাময়িক রাইটারদের (concurrent writers) বাধা দেয় এবং অলস কানেকশনটি (idle connection) পুল শেষ করে দিতে পারে, যার ফলে নতুন কলকারীদের একটি ফ্রি স্লটের জন্য অপেক্ষা করতে হয়।

চারটি স্বল্পস্থায়ী প্যাটার্ন

গাইডটি পরামর্শ দিচ্ছে যে কনসিস্টেন্সি বা সামঞ্জস্যতাকে পুরো কথোপকথনের পরিবর্তে প্রতিটি টুল-কলের (per-tool-call) বিষয় হিসেবে বিবেচনা করা উচিত। চারটি প্যাটার্ন হলো:

  1. লাইভ স্টেটমেন্টস (Live statements) – প্রতিটি কল ডিফল্ট আইসোলেশন লেভেলের (isolation level) অধীনে চলে এবং শুধুমাত্র সেই ডেটা দেখতে পায় যা এক্সিকিউশনের মুহূর্তে কমিট (commit) করা হয়েছে। এটি সবচেয়ে সহজ মডেল; এখানে কলকারী মেনে নেন যে পূর্ববর্তী টার্নের পর ডেটা পরিবর্তিত হতে পারে।
  2. বাউন্ডেড ট্রানজ্যাকশন (Bounded transactions) – একজন ডেভেলপার কয়েকটি স্টেটমেন্টকে একটি ছোট ট্রানজ্যাকশনের মধ্যে গ্রুপ করেন যা পরবর্তী LLM টার্নের আগেই শেষ হয়ে যায়। এটি টুল কলের বাইরে না থেকে সেই ব্যাচের জন্য অ্যাটমিসিটি (atomicity) নিশ্চিত করে।
  3. স্ন্যাপশট রিডস (Snapshot reads) – অপারেশনটি একটি নির্দিষ্ট স্ন্যাপশট টাইমস্ট্যাম্প দিয়ে শুরু হয়, যা কলের সময়কাল জুড়ে ডাটাবেসের একটি স্থিতিশীল ভিউ প্রদান করে। সমসাময়িক রাইট (concurrent writes) চললেও কলের মধ্যে সমস্ত রিড একই ডেটা দেখতে পায়।
  4. মেটেরিয়ালাইজড রিপোর্টস (Materialized reports) – টুলটি একটি পূর্ব-তৈরি করা, ভার্সনযুক্ত রেজাল্ট সেট থেকে ডেটা পড়ে যা একটি নির্দিষ্ট কাট-অফ পয়েন্টে ডাটাবেসের অবস্থা প্রতিফলিত করে। এরপর পেজিনেশন (pagination) বা পরবর্তী গণনাগুলো সেই স্থির ডেটাসেটের ওপর কাজ করে।

SQL Server-এ, READ_COMMITTED_SNAPSHOT সক্রিয় আছে কি না তা পরীক্ষা করুন। শুধুমাত্র নাম দেখে সবকিছু বুঝে নেওয়ার ভুল করবেন না।

LLM-চালিত অ্যাপের জন্য ব্যবহারিক নিয়মাবলী

  • প্রয়োজনীয় বিষয়গুলো ব্যাচ আকারে নিন (Batch what you need) – যদি একটি প্রশ্নের জন্য অনেকগুলো ভ্যালুর প্রয়োজন হয়, তবে আলাদা আলাদা কুয়েরি না পাঠিয়ে (যেগুলোর প্রতিটি একটি নতুন ট্রানজ্যাকশন শুরু করে) একটি মাত্র টুল কলের মাধ্যমে সেগুলো গণনা করুন।
  • ডিটারমিনিস্টিক পেজিনেশন (Deterministic pagination) – বিভিন্ন পেজে ফলাফল দেখানোর সময় একটি স্থিতিশীল অর্ডারিং কী (ordering key), একটি কার্সার (cursor), অথবা একটি মেটেরিয়ালাইজড রেজাল্ট সেট ব্যবহার করুন। ব্যবহারকারী স্ক্রল করার সময় কখনোই একটি ট্রানজ্যাকশন খোলা রাখবেন না।
  • প্রমাণ বা এভিডেন্স প্রদান করুন (Return evidence) – ডেটার পাশাপাশি এমন মেটাডেটা অন্তর্ভুক্ত করুন যা কনসিস্টেন্সি মডেলটিকে স্পষ্ট করে তোলে: কনসিস্টেন্সি ক্লাস, স্ন্যাপশট শুরুর সময়, রিপোর্টিং কাট-অফ, ডেটার সতেজতা (freshness), রো কাউন্ট, ডাটাবেস আইডেন্টিটি এবং একটি ট্রেস আইডি (trace ID)।
  • কনকারেন্সি দিয়ে স্ট্রেস-টেস্ট করুন (Stress-test with concurrency) – LLM প্রম্পট করার সময় সমসাময়িক রাইট (concurrent writes) সিমুলেট করুন এবং যাচাই করুন যে অ্যাপ্লিকেশনটি সঠিকভাবে রিট্রাই (retry) করছে বা বিকল্প ব্যবস্থা গ্রহণ করছে কি না।

মূল কথাটি পরিষ্কার: একটি AI চ্যাট ডাটাবেস ট্রানজ্যাকশনের জীবনকাল নির্ধারণ করবে না। প্রতিটি টুল কলের মধ্যে কনসিস্টেন্সির পরিধি সীমাবদ্ধ রেখে ডেভেলপাররা ডাটাবেসকে সুস্থ রাখতে পারেন, সকল ব্যবহারকারীর জন্য পারফরম্যান্স বজায় রাখতে পারেন এবং LLM-কে সঠিকভাবে উত্তর দেওয়ার জন্য যথেষ্ট নির্ভরযোগ্য ডেটা প্রদান করতে পারেন।