আমি বিকাশকারী দৃষ্টিকোণ থেকে একটি উত্তর সরবরাহ করব।
আমার মতে, আপনি যখন বর্ণনা করেছেন এমন কোনও সারি বিতর্কটির মুখোমুখি হন, তখন আপনার অ্যাপ্লিকেশনটিতে আপনার বাগ রয়েছে। বেশিরভাগ ক্ষেত্রে এই ধরণের বিতর্ক একটি হারানো-আপডেট দুর্বলতার লক্ষণ। আসকটমের এই থ্রেডটি একটি হারানো আপডেটের ধারণাটি ব্যাখ্যা করে:
একটি হারানো আপডেট ঘটে যখন:
অধিবেশন 1: টমের কর্মচারী রেকর্ড পড়ুন
সেশন 2: টমের কর্মচারী রেকর্ড পড়ুন
সেশন 1: টমের কর্মচারী রেকর্ড আপডেট করুন
সেশন 2: টমের কর্মচারী রেকর্ড আপডেট করুন
সেশন 2 সেশন 1 এর পরিবর্তনগুলি কখনও না দেখে লিখিত থাকবে - ফলস্বরূপ আপডেটটি হারিয়েছে lost
আপনি হারানো আপডেটের একটি বাজে পার্শ্ব-প্রতিক্রিয়াটির অভিজ্ঞতা পেয়েছেন: অধিবেশন 2 অবরুদ্ধ করা যেতে পারে কারণ সেশন 1 এখনও কমিট করেনি। তবে প্রধান সমস্যাটি হ'ল সেশন 2 অন্ধভাবে রেকর্ডটি আপডেট করে। মনে করুন যে উভয় অধিবেশন বিবৃতি জারি করে:
UPDATE table SET col1=:col1, ..., coln=:coln WHERE id = :pk
উভয় বক্তব্যের পরে, সেশন 1 এর পরিবর্তনগুলি ওভাররাইট করা হয়েছে, সেশনের 2 ছাড়াই সেশন 1 দ্বারা সারিটি পরিবর্তন করা হয়েছে তা অবহিত করা হয়নি।
হারানো আপডেট (এবং বিতর্ক পার্শ্ব প্রতিক্রিয়া) কখনই ঘটবে না, সেগুলি 100% এড়ানো যায়। দুটি প্রধান পদ্ধতির সাথে তাদের প্রতিরোধ করার জন্য আপনার লকিং ব্যবহার করা উচিত: আশাবাদী এবং নিরাশাবাদী লকিং ।
1) হতাশাবাদী লকিং
আপনি একটি সারি আপডেট করতে চান। এই মোডে আপনি অন্যকে এই সারিতে সংশোধন করতে বাধা দেবেন row সারিটিতে একটি লক অনুরোধ করে ( SELECT ... FOR UPDATE NOWAIT
বিবৃতি)। যদি সারিটি ইতিমধ্যে সংশোধন করা হচ্ছে তবে আপনি একটি ত্রুটি বার্তা পাবেন যা আপনি চূড়ান্তভাবে শেষ ব্যবহারকারীর কাছে অনুবাদ করতে পারেন (এই সারিটি অন্য কোনও ব্যবহারকারী দ্বারা সংশোধিত হচ্ছে)। যদি সারিটি উপলভ্য থাকে তবে আপনার সংশোধনীগুলি (আপডেট করুন) করুন, তারপরে আপনার লেনদেন শেষ হলেই কমিট করুন।
2) আশাবাদী লকিং
আপনি একটি সারি আপডেট করতে চান। তবে, আপনি এই সারিতে একটি লক বজায় রাখতে চান না, সম্ভবত আপনি সারিটি আপডেট করার জন্য বেশ কয়েকটি লেনদেন ব্যবহার করেছেন (ওয়েব ভিত্তিক স্টেটলেস অ্যাপ্লিকেশন), অথবা সম্ভবত আপনি কোনও ব্যবহারকারীকে খুব বেশি সময় ধরে লক ধরে রাখতে চান না ( যার ফলে অন্য লোকেরা অবরুদ্ধ হতে পারে)। সেক্ষেত্রে আপনি এখনই একটি লকের জন্য অনুরোধ করবেন না। আপনার আপডেট জারি করা হবে সারিটি পরিবর্তিত হয়নি তা নিশ্চিত করার জন্য আপনি একটি চিহ্নিতকারী ব্যবহার করবেন। আপনি সমস্ত কলামের মান ক্যাশে করতে পারেন বা আপনি এমন টাইমস্ট্যাম্প কলাম ব্যবহার করতে পারেন যা স্বয়ংক্রিয়ভাবে আপডেট হয় বা সিকোয়েন্স ভিত্তিক কলাম। আপনার পছন্দ যাই হোক না কেন, আপনি যখন নিজের আপডেটটি সম্পাদন করতে চলেছেন, আপনি নিশ্চিত করবেন যে এই সারিটির চিহ্নিতকারী কোনও কোয়েরি জারি করে পরিবর্তিত হয়নি:
SELECT <...>
FROM table
WHERE id = :id
AND marker = :marker
FOR UPDATE NOWAIT
যদি ক্যোয়ারী একটি সারিতে ফিরে আসে, আপনার আপডেট করুন। যদি এটি না হয়, এর অর্থ হ'ল আপনি যখন শেষ বার অনুসন্ধান করেছিলেন তখন থেকেই কেউ সারিটি পরিবর্তন করেছে। আপনাকে প্রক্রিয়াটি শুরু থেকেই পুনরায় চালু করতে হবে।
দ্রষ্টব্য: আপনার ডিবি অ্যাক্সেস করে এমন সমস্ত অ্যাপ্লিকেশনগুলির উপরে যদি আপনার সম্পূর্ণ বিশ্বাস থাকে তবে আপনি আশাবাদী লকিংয়ের জন্য সরাসরি আপডেটের উপর নির্ভর করতে পারেন। আপনি সরাসরি ইস্যু করতে পারেন:
UPDATE table
SET <...>,
marker = marker + 1
WHERE id = :id;
যদি বিবৃতিটি কোনও সারি আপডেট না করে তবে আপনি জানেন যে কেউ এই সারিটি পরিবর্তন করেছে এবং আপনাকে সর্বদা শুরু করা দরকার।
যদি সমস্ত অ্যাপ্লিকেশনগুলি এই স্কিমের সাথে একমত হয় তবে আপনাকে অন্য কারও দ্বারা অবরুদ্ধ করা হবে না এবং আপনি অন্ধ আপডেটটি এড়াতে পারবেন। তবে, আপনি যদি সারিটি আগেই লক না করে থাকেন তবে অন্য অ্যাপ্লিকেশন, ব্যাচের কাজ বা সরাসরি আপডেট আশাবাদী লকিং বাস্তবায়ন না করলে আপনি এখনও অনির্দিষ্টকালের জন্য লক করার জন্য সংবেদনশীল। এই কারণেই আমি সর্বদা সারিটিকে লক করার পরামর্শ দিই, আপনার লকিং স্কিমের পছন্দ যাই হোক না কেন (আপনি যখন সারিটি লক করে রাখেন তখন রোউইড সহ সমস্ত মান পুনরুদ্ধার করায় পারফরম্যান্স হিট নগণ্য হতে পারে)।
টি এল; ডিআর
- এর আগে লক না রেখে কোনও সারি আপডেট করা অ্যাপ্লিকেশনটিকে সম্ভাব্য "হিমায়িত" করে দেয়। যদি ডিবি থেকে সমস্ত ডিএমএল আশাবাদী বা নিরাশাবাদী লক প্রয়োগ করে তবে এড়ানো যায়।
- যাচাই করে নিন যে নির্বাচন বৈদ্যুতিন ফেরতের মানগুলি পূর্ববর্তী কোনও নির্বাচনের সাথে সামঞ্জস্যপূর্ণ (কোনও হারানো আপডেট সমস্যা এড়াতে)