2013-08-04 2 views
6

मैं तालिका (पंक्तियों) का उपयोग करके तालिका की एक पंक्ति अपडेट करता हूं, लेकिन "sp_lock" को निष्पादित करके मैं देख सकता हूं कि पूरी तालिका है बंद कर दिया। इसलिए, लेनदेन करने से पहले, अन्य लेन-देन तालिका की अन्य पंक्तियों को अपडेट नहीं कर सकते हैं। क्यों "के साथ (ROWLOCK)" प्रभावी नहीं होता है?"तालिका (रोलॉक)" के साथ पूरी तालिका लॉक हो जाती है, जबकि अपडेट स्टेटमेंट

मैं नीचे क्वेरी चप्पू-आंकड़ा के साथ उपयोग कर रहा हूँ: एक ही समय में किसी भी अन्य लेन-देन से एक ही तालिका में अंतर पंक्ति के लिए एक ही हटाने आपरेशन चल रहा

DELETE FROM DefDatabaseSession WITH (ROWLOCK) WHERE ProcessName='test'; 

मैं अपवाद

[हो रही है एसक्यूएलसेवर जेडीबीसी चालक] [एसक्यूएल सर्वर] लॉक अनुरोध समय अवधि समाप्त हो गया .; नेस्टेड अपवाद java.sql.SQLException है: [newscale] [SQLServer जेडीबीसी चालक] [SQLServer] लॉक अनुरोध समय अवधि समाप्त हो गई है .: com.newscale.bfw.udkernel.kernel.UdKernelException: udconfig.defdbsession.delete; SQL के लिए अनुक्रमित SQLException [DefDatabaseSession से हटाएं जहां प्रक्रिया नाम =?]; एसक्यूएल राज्य [एचवाई 000]; त्रुटि कोड [1222]; [न्यूज़केल] [एसक्यूएलसेवर जेडीबीसी चालक] [एसक्यूएल सर्वर] लॉक अनुरोध समय अवधि समाप्त हो गया .; नेस्टेड अपवाद java.sql.SQLException है: [newscale] [SQLServer जेडीबीसी चालक] [एसक्यूएल सर्वर] लॉक अनुरोध समय अवधि समाप्त हो गया।

उत्तर

2

कारण यह है कि ऑप्टिमाइज़र आपकी पंक्ति लॉक संकेत को अनदेखा कर रहा है [के साथ (ROWLOCK) ऑप्टिमाइज़र को एक क्वेरी संकेत प्रदान करता है]। यह उन परिस्थितियों में होगा जहां आप पंक्तियों की एक बड़ी संख्या को मार रहे हैं, ऐसे परिदृश्यों में ऑप्टिमाइज़र को आपकी तालिका पर स्कैन ढेर करने के लिए और अधिक व्यवहार्य लगता है और इसलिए टेबल लॉक प्राप्त करें।

विस्तृत चर्चा आप इस लिंक पर जा सकते हैं के लिए: http://social.msdn.microsoft.com/Forums/sqlserver/en-US/60238304-04e8-4f98-84d1-3ddf1ed786a9/why-the-entire-table-is-locked-while-with-rowlock-is-used-in-a-update-statement

0

मेरा अनुमान है कि आप ProcessName पर एक सूचकांक की जरूरत नहीं है, तो क्वेरी एक पूर्ण तालिका स्कैन, इस प्रकार सभी पंक्तियों को पढ़ रहे हैं क्या करना चाहिए है (और हटाने के लिए संभावित उम्मीदवार हैं), इसलिए प्रत्येक पंक्ति को लॉक करने से पूरी तालिका को लॉक करना अधिक कुशल है।

एक सूचकांक को परिभाषित करने का प्रयास करें:

CREATE INDEX DefDatabaseSession_ProcessName ON DefDatabaseSession(ProcessName); 

आप एक समझाने करके क्वेरी योजना पता कर सकते हैं:

EXPLAIN DELETE FROM DefDatabaseSession WITH (ROWLOCK) WHERE ProcessName='test'; 
+1

'EXPLAIN' SQL सर्वर पर मौजूद नहीं है। योजना प्राप्त करने के लिए "वास्तविक निष्पादन योजना शामिल करें" बटन का उपयोग करें। – Alejandro

+0

मेरे पास ProcessName कॉलम के लिए एक अनुक्रमणिका है। – vani

+0

लेकिन मुझे केवल पंक्ति लॉक की आवश्यकता है ... क्योंकि अन्य पंक्तियों को किसी अन्य थ्रेड द्वारा एक ही समय में हटा दिया जाएगा .. इसलिए मुझे केवल अपने राक्षसों को ढीला करने की ज़रूरत नहीं है .. इसलिए मैं टेबल लॉक का उपयोग नहीं कर सकता – vani

संबंधित मुद्दे