DB काम पर बहुत नौसिखिया, इसलिए एक बुनियादी सवाल के साथ अपने धैर्य की सराहना करें। मैं अपने स्थानीय मशीन पर SQL सर्वर 2014 चला रहा हूं, और मेरे पास अलग-अलग तरीकों का परीक्षण करने के लिए एक छोटी सी मेज और एक बुनियादी क्लाइंट एप्लिकेशन है। मुझे लग रहा है कि दोनों INSERT INTOऔर UPDATEबयानों के दौरान टेबल लॉक होना क्या प्रतीत होता है । ग्राहक निम्नलिखित कोड के साथ एक ASP.NET अनुप्रयोग है:
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एड को छोड़कर सभी पंक्तियों को पढ़ते हैं । UPDATEअन्य थ्रेड्स की क्वेरी करने से पहले पंक्ति के आरंभिक संस्करण को UPDATEएड किया जाना पढ़ें । क्या कोई और तरीका है इसे करने के लिए? अगर मुझे अपने उपयोग के मामले को स्पष्ट करने के लिए अन्य जानकारी प्रदान करने की आवश्यकता है तो कृपया मुझे बताएं। धन्यवाद।
newkey" something';DELETE FROM LAYOUTSv2 --" पर सेट होता है । आपका अपडेट सफलतापूर्वक पूरा हो जाएगा, और फिर तालिका को खाली कर दें क्योंकि उपयोगकर्ता ने एपोस्ट्रोफ डालकर क्वेरी को हेरफेर किया था। आम तौर पर, एक पैरामीटर की गई क्वेरी कुछ ऐसी दिखती है UDPATE LAYOUTSv2 SET LAYOUTS_enabled_b='-3' WHERE LAYOUTS_key=?, जिसके बाद आप ?अपने कोड में अलग से मान (ओं) को (पैरामीटर) असाइन करते हैं।
WHERE LAYOUTS_key='" + newkey + "', SQL इंजेक्शन सहित विभिन्न कारणों के लिए एक पूर्ण नहीं-नहीं है, आपको पैरामीटर प्रश्नों का उपयोग करना चाहिए।