এমএস এসকিউএল সার্ভারে পুরো টেবিলটি লক না করার জন্য কীভাবে এসকিউএল সন্নিবেশ এবং / অথবা আপডেট পাবেন get


13

ডিবি কাজের ক্ষেত্রে একজন নবাগত, সুতরাং একটি মৌলিক প্রশ্ন সহ আপনার ধৈর্যকে প্রশংসা করুন। আমি আমার স্থানীয় মেশিনে এসকিউএল সার্ভার 2014 চালাচ্ছি এবং এর সাথে বিভিন্ন পদ্ধতির পরীক্ষা করার জন্য আমার কাছে একটি ছোট টেবিল এবং একটি বেসিক ক্লায়েন্ট অ্যাপ্লিকেশন রয়েছে। আমি উভয় INSERT INTOএবং UPDATEবিবৃতি সময় একটি টেবিল লক হিসাবে প্রদর্শিত হবে তা পাচ্ছি । ক্লায়েন্টটি নিম্নলিখিত কোড সহ একটি এএসপি.এনইটি অ্যাপ্লিকেশন:

OleDbConnection cn = new OleDbConnection("Provider=SQLNCLI11; server=localhost\\SQLEXPRESS; Database=<my db>; user id=<my uid>; password=<my pwd>");
cn.Open();
OleDbTransaction tn = cn.BeginTransaction();
OleDbCommand cmd = new OleDbCommand("INSERT INTO LAYOUTSv2 (LAYOUTS_name_t, LAYOUTS_enabled_b, LAYOUTS_data_m) VALUES ('name', '-1', 'data')", cn, tn);
cmd.ExecuteNonQuery();
cmd.CommandText = "SELECT SCOPE_IDENTITY()";
int newkey = Decimal.ToInt32((decimal)cmd.ExecuteScalar());
Console.WriteLine("Created index " + newkey);
Thread.Sleep(15000);
tn.Commit();
tn = cn.BeginTransaction();
cmd.CommandText = "UDPATE LAYOUTSv2 SET LAYOUTS_enabled_b='-3' WHERE LAYOUTS_key='" + newkey + "'";
cmd.Transaction = tn;
cmd.ExecuteNonQuery();
Console.WriteLine("updated row");
Thread.Sleep(15000);
tn.Rollback();
cn.Close();

আমি এই কোডটি চালনা করি, তারপরে আমি পরিচালিত স্টুডিও থেকে SELECT * FROM LAYOUTSv2। উভয় ক্ষেত্রে ক্লায়েন্টের থ্রেড থেমে থাকলে (যেমন প্রতিশ্রুতিবদ্ধ / রোলব্যাকের আগে) কমপ্লেট / রোলব্যাক না হওয়া পর্যন্ত নির্বাচিত প্রশ্নটি স্থগিত থাকে।

সারণীতে LAYOUTS_key ক্ষেত্রটি প্রাথমিক কী হিসাবে নির্ধারিত রয়েছে। বৈশিষ্ট্য উইন্ডোতে এটি দেখায় যে এটি অনন্য এবং গোষ্ঠীযুক্ত, পৃষ্ঠা লক এবং সারি লক উভয়ই অনুমোদিত। টেবিলের জন্য লক বর্ধন সেটিংটি অক্ষম করা আছে ... আমি কোনও পরিবর্তন ছাড়াই টেবিল এবং অটো উপলভ্য অন্য দুটি সেটিংস চেষ্টা করেছি। আমি চেষ্টা করেছি SELECT ... WITH (NOLOCK)এবং এটি অবিলম্বে ফলাফলটি ফিরে পেয়েছে, তবে এখানে এবং অন্যান্য জায়গায় যেমন সতর্কতা অবলম্বন করা হচ্ছে তবে আমার কাজটি করা উচিত নয়। আমি ROWLOCKউভয় বক্তব্য INSERTএবং UPDATEবিবৃতিতে ইঙ্গিত দেওয়ার চেষ্টা করেছি , কিন্তু কিছুই পরিবর্তন হয়নি।

আমি যে আচরণটি সন্ধান করছি তা হ'ল: প্রতিশ্রুতি দেওয়ার আগে INSERT, অন্যান্য থ্রেডের অনুসন্ধানগুলি INSERTএড হওয়া ব্যতীত সমস্ত সারি পড়বে read UPDATEঅন্যান্য থ্রেডের কোনও প্রশ্নের প্রতিশ্রুতি দেওয়ার আগে UPDATEএড হওয়ার সারিটির প্রারম্ভিক সংস্করণটি পড়ুন । আমি কি এটি করার কোন উপায় আছে? আমার ব্যবহারের কেসটি পরিষ্কার করতে আমার যদি অন্য তথ্য সরবরাহ করতে হয় তবে দয়া করে আমাকে জানান। ধন্যবাদ।


3
যাইহোক, WHERE LAYOUTS_key='" + newkey + "'এসকিউএল ইঞ্জেকশন সহ বিভিন্ন কারণে সম্পূর্ণ নোংরা, আপনার প্যারামিটারাইজড ক্যোয়ারী ব্যবহার করা উচিত।
মার্টিন স্মিথ

1
@ মার্টিনস্মিত এটি সম্পর্কে মাথাব্যথার জন্য ধন্যবাদ ... প্যারামিটারাইজড কোয়েরি বা এসকিউএল ইঞ্জেকশন হামলার কথা কখনও শুনেনি।
জন রিহেল

@ জনআরহিল, পুনরায়: ইনজেকশন আক্রমণগুলি, আপনার ব্যবহারকারী newkey" something';DELETE FROM LAYOUTSv2 --" সেট করে কিনা তা কল্পনা করুন । আপনার আপডেটটি সফলভাবে সমাপ্ত হবে, এবং তারপরে টেবিলটি খালি করবে কারণ ব্যবহারকারী কোনও অ্যাডোস্ট্রোফ inুকিয়ে ক্যোয়ারীটি পরিচালনা করেছিলেন। সাধারণত, একটি প্যারামিটারাইজড ক্যোয়ারী এমন কিছু দেখায় UDPATE LAYOUTSv2 SET LAYOUTS_enabled_b='-3' WHERE LAYOUTS_key=?যা পরে আপনি আলাদাভাবে ?আপনার কোডের (প্যারামিটার) মান (গুলি) বরাদ্দ করেন ।
ড্যানিয়েল হুটমাচার

উত্তর:


10

সম্ভাবনা হ'ল এটি "পুরো টেবিলটি" লক করছে না।

এটি টেবিলের মধ্যে একটি সারি লক করছে তবে আপনার SELECT * FROM LAYOUTSv2পুরো টেবিলটি পড়ার চেষ্টা করছে যাতে অগত্যা সেই লকটি আটকা পড়ে।

সন্নিবেশের ক্ষেত্রে আপনি কেবল READPASTলক করা সারিটি পেরিয়ে যাওয়ার ইঙ্গিতটি নির্দিষ্ট করতে পারেন - তবে এটি UPDATEক্ষেত্রে আপনার পছন্দসই ফলাফল দেয় না (এটি আবার সারিটি এড়িয়ে যাবে সারিটির প্রারম্ভিক সংস্করণটি পড়বে না)।

যদি আপনি পড়ার প্রতিশ্রুতিবদ্ধ স্ন্যাপশট বিচ্ছিন্নতার জন্য ডেটাবেস কনফিগার করেন তবে এটি উভয় ক্ষেত্রেই আপনার পছন্দসই প্রভাব দেবে (এর বৃহত্তর ব্যবহারের ব্যয়ে tempdb)


আমি "ইজ রিড কমিটেড স্ন্যাপশট চালু" কে সত্যে পরিবর্তন করেছি এবং এখন এটি কোনও ইঙ্গিতের প্রয়োজন ছাড়া নিখুঁতভাবে কাজ করে। ধন্যবাদ! একটি ফলোআপ ... আমি "স্ন্যাপশট বিচ্ছিন্নকরণের অনুমতি দিন" মিথ্যাতে সেট করে রেখেছি ... এটি ঠিক আছে? ধন্যবাদ।
জন রিহেল

@ জনআরহিল - হ্যাঁ যদি আপনি স্পষ্টভাবে SNAPSHOTবিচ্ছিন্নতা এটিকে অক্ষম রেখে দেওয়ার জন্য সর্বোত্তমভাবে ব্যবহার না করে থাকেন এবং পরে যদি আপনি পরবর্তীকালে সিদ্ধান্ত নেন এটি আপনার পক্ষে কার্যকর হবে তবে এটি সক্ষম করে দিন।
মার্টিন স্মিথ

7

সন্নিবেশ এবং আপডেটের বিবৃতিগুলি সারি-স্তরের লক তৈরি করার কথা। যাইহোক, যখন কোনও লেনদেনে লকের সংখ্যা 5,000 বা তার বেশি হয় তখন একটি লক বৃদ্ধি ঘটে এবং এটি একটি সারণী স্তরের লক তৈরি করে। দয়া করে নীচে দেখুন.

https://technet.microsoft.com/en-us/library/ms184286(v=sql.105).aspx


এই প্রশ্নের সাথে প্রাসঙ্গিক নয় কেননা ইনসার্ট এবং আপডেট আপডেট উভয় বিবৃতিই একক সারিতে লিখছে
মার্টিন স্মিথ
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.