2012-01-13 16 views
25

MySQL दस्तावेज़ के अनुसार, MySQL एकाधिक ग्रैन्युलरिटी लॉकिंग (एमजीएल) का समर्थन करता है।MySQL 'अपडेट के लिए चयन करें' व्यवहार

मामला-1

खोला टर्मिनल -1:

// जुड़ा MySQL के लिए

mysql> start transaction; 
Query OK, 0 rows affected (0.00 sec) 

mysql> select id, status from tracking_number limit 5 for update; 
+----+--------+ 
| id | status | 
+----+--------+ 
| 1 |  0 | 
| 2 |  0 | 
| 3 |  0 | 
| 4 |  0 | 
| 5 |  0 | 
+----+--------+ 
5 rows in set (0.00 sec) 
mysql> 

इसे खोला छोड़ दिया और खोला टर्मिनल -2:

// mysql से जुड़ा

mysql> start transaction; 
Query OK, 0 rows affected (0.00 sec) 

mysql> select id, status from tracking_number limit 5 for update; 

<!-- Hangs here. and after some time it says--> 
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction 

हालांकि पुनर्प्राप्त करने के लिए बहुत सारी पंक्तियां हैं, टी 2 पूरा होने तक टी 2 प्रतीक्षा करता है।

मामला-2

वाम टर्मिनल -1 is.Now के रूप में टर्मिनल -2 में:

mysql> start transaction; 
Query OK, 0 rows affected (0.00 sec) 

<!-- case 2.1 --> 
mysql> select id, status from tracking_number where id=1; 
+----+--------+ 
| id | status | 
+----+--------+ 
| 1 |  0 | 
+----+--------+ 
1 row in set (0.00 sec) 

mysql> select id, status from tracking_number where id=2; 
+----+--------+ 
| id | status | 
+----+--------+ 
| 2 |  0 | 
+----+--------+ 
1 row in set (0.00 sec) 

<!-- case 2.2 --> 
mysql> select * from tracking_number where id=2 for update; 
<!-- Hangs here. and after some time --> 
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction 
  1. लेकिन मामला 1 में, टी 2 पंक्तियों के एक ही सेट के लिए इंतजार कर रहा है कि टी 1 बंद कर दिया है?

  2. क्या इसका मतलब असंबद्ध चयन क्वेरी (यहां तक ​​कि लिमिट पैरामीटर के साथ भी है। मैंने अलग-अलग सीमा के साथ भी कोशिश की है) पूरी तालिका को अवरुद्ध करता है?

  3. रिकॉर्ड के क्षेत्र को निर्दिष्ट किए बिना लेनदेन को स्वतंत्र रूप से लॉक करने का कोई तरीका है (यानी, का उपयोग किए बिना फ़ील्ड = मान)?
  4. आम तौर पर (या जावा समवर्ती लॉकिंग के अनुसार), लॉक लिखना अनन्य है और पढ़ा नहीं जाता है। 2.1 के मामले में, हालांकि रिकॉर्ड लॉक मोड में हैं, टी 2 एक ही रिकॉर्ड कैसे पढ़ सकता है? चूंकि इसकी अनुमति है इसे लॉक करने में क्या बिंदु है?
  5. केस 2.2 समझा जाता है।

एक टर्मिनल और लेन-देन खोला गया:

mysql> update tracking_number set status=4 where status=0 limit 5; 
Query OK, 5 rows affected (0.00 sec) 
Rows matched: 5 Changed: 5 Warnings: 0 

वाम यह वहाँ और एक अन्य टर्मिनल और लेन-देन खोला:

mysql> update tracking_number set status=5 where status=0 limit 5; 

टी 2 सफल नहीं हुआ जब तक मैं प्रतिबद्ध (या रोलबैक) टी 1।

  1. यह व्यवहार क्यों है?

उत्तर

22

मुझे अपने मामलों के माध्यम से जाना और यह बताएं कि इन ताले काम करने दें:

1 मामले

T1 अपने परीक्षण तालिका में कुछ पंक्तियां अपडेट करना चाहता है। यह लेनदेन पहली तालिका में सभी तालिका और एक्स लॉक पर आईएक्स लॉक रखता है।

टी 2 आपकी टेस्ट टेबल में कुछ पंक्तियों को अपडेट करना चाहता है।यह लेनदेन आईएक्स (क्योंकि IX के साथ संगत IX) को सभी तालिकाओं पर लॉक करता है और पहले 5 पंक्तियों का प्रयास करता है लेकिन यह ऐसा नहीं कर सकता क्योंकि एक्स एक्स

से संगत नहीं है तो हम ठीक हैं।

2,1 मामले

T1 अपने परीक्षण तालिका में कुछ पंक्तियां अपडेट करना चाहता है। इस लेनदेन ने सभी 5 पंक्तियों पर एक्सएक्स लॉक और पहली 5 पंक्तियों पर एक्स लॉक लगाया।

टी 2 आपकी टेस्ट टेबल से कुछ पंक्तियों का चयन करना चाहता है। और यह किसी भी ताले जगह नहीं है (क्योंकि InnoDB गैर ताला प्रदान करता है पढ़ता है)

2,1 मामले

T1 अपने परीक्षण तालिका में कुछ पंक्तियां अपडेट करना चाहता है। इस लेनदेन ने सभी 5 पंक्तियों पर एक्सएक्स लॉक और पहली 5 पंक्तियों पर एक्स लॉक लगाया।

टी 2 आपकी टेस्ट टेबल से कुछ पंक्तियों को अपडेट करना (अद्यतन के लिए चयन करना) चाहता है। प्लेस पूरी तालिका पर है और पंक्ति पर एस लॉक प्राप्त करने का प्रयास करता है और विफल रहता है क्योंकि एक्स और एस असंगत हैं।


इसके अलावा हमेशा अलगाव स्तर के बारे में पता होना: अलग स्तर कारण अलग तंत्र मुक्त/ताले

आशा है कि यह मदद करता है

+0

धन्यवाद @ravnur प्राप्त करने के लिए। रिकॉर्ड के क्षेत्र को निर्दिष्ट किए बिना लेनदेन को स्वतंत्र रूप से लॉक करने का कोई तरीका है (यानी, फ़ील्ड = मान का उपयोग किए बिना)? –

+1

स्वतंत्र रूप से = एक साथ? यदि "हां" अलगाव स्तर को "डर्टी रीड्स" को छोड़कर इसे करने का कोई तरीका नहीं है (आप बेहतर विकल्प इस विकल्प को आजमाएं नहीं)। यदि आपका उत्तर "नहीं" है, तो आप 'लॉक टेबल' का प्रयास कर सकते हैं या अलगाव स्तर को "सरलीकृत" के रूप में सेट कर सकते हैं (लेकिन मुझे लगता है कि आपका उत्तर "हां" होना चाहिए)। – ravnur

+0

मेरा जवाब "हाँ" है। अपना स्पष्टीकरण के लिए धन्यवाद। उत्तर के लिए –

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