2008-11-06 14 views
8

मैं अपनी पाइथन लाइब्रेरी को MySQLdb के साथ काम करना चाहता हूं और मृतकों का पता लगाने में सक्षम हूं। मेरा मानना ​​है कि मैंने एक अच्छा समाधान कोड किया है, और अब मैं इसका परीक्षण करना चाहता हूं।मैं परीक्षण प्रयोजनों के लिए MySQL में एक डेडलॉक का कारण कैसे बना सकता हूं

डेडलॉक स्थिति बनाने के लिए MySQLdb का उपयोग करके चलने वाले सबसे सरल प्रश्नों के लिए कोई भी विचार होगा?

प्रणाली की जानकारी:

  • MySQL 5.0.19
  • ग्राहक 5.1.11
  • Windows XP
  • अजगर 2.4/MySQLdb 1.2.1 p2

उत्तर

1

आप हमेशा चला सकते हैं लॉक टेबल एक अन्य सत्र से टैबलेटनाम (उदाहरण के लिए mysql सीएलआई)। वह चाल हो सकता है।

यह तब तक लॉक रहेगा जब तक कि आप इसे रिलीज़ न करें या सत्र को डिस्कनेक्ट न करें।

+0

यह केवल एक ऑपरेशनल एरर का कारण बनता है: (1205, 'लॉक प्रतीक्षा टाइमआउट पार हो गया; लेनदेन को पुनरारंभ करने का प्रयास करें'), नहीं? – Greg

+0

@ ग्रेग: मुझे लगता है कि वे लॉक टेबल ए कर रहे एक सत्र के बारे में बात कर रहे हैं, और एक और सत्र लॉक टेबल बी कर रहा है। इस बिंदु पर किसी को सिंक्रनाइज़ करना है। फिर सत्र एक लॉक टेबल बी का प्रयास करता है। जब सत्र दो लॉक टेबल ए का प्रयास करता है - यह डेडलॉक होगा। –

1

मैं पाइथन के साथ familar नहीं हूँ, तो मेरी गलत भाषा बहाना अगर मैं यह गलत कह रहा हूँ ... लेकिन दो सत्र खोलें (अलग खिड़कियों में, या अलग पायथन प्रक्रियाओं से - अलग बक्से से काम करेगा ...) फिर ...

। सत्र ए में:

Begin Transaction 
     Insert TableA() Values()... 

। फिर सत्र बी में:

Begin Transaction 
    Insert TableB() Values()... 
    Insert TableA() Values() ... 

। फिर वापस सत्र एक

Insert TableB() Values() ... 

के पास जाओ तुम एक गतिरोध मिल जाएगा ...

+0

मैं कैसे सुनिश्चित करूंगा कि वे एक ही समय में चलते हैं? – Greg

+0

क्षमा करें, मेरा मतलब है "मैन्युअल रूप से" नियंत्रण करना जब उपरोक्त तीन चरणों में से प्रत्येक को निष्पादित किया जाता है ... सबसे पहले, लेनदेन शुरू करें और सत्र ए में टैब को सम्मिलित करें, फिर दूसरी प्रक्रिया में जाएं और दूसरा खंड करें, फिर पहले स्थानांतरित करें प्रक्रिया और (शायद यह करने के लिए एक उपयोगकर्ता बटन है) अंतिम चंक को निष्पादित करें –

+0

पायथन या किसी अन्य क्लाइंट कोड का उपयोग किए बिना, मैं केवल दो SQL विंडो में सम्मिलित कथन लिखूंगा, और एक से दूसरे में आगे बढ़ता हूं .. लेकिन आप अपने कोड को "जाल" और डेडलॉक का पता लगाना चाहते हैं ... –

1

आप निम्नलिखित लाइनों के साथ कुछ करना चाहता हूँ।

parent.py

import subprocess 
c1= subprocess.Popen(["python", "child.py", "1"], stdin=subprocess.PIPE, stdout=subprocess.PIPE) 
c2= subprocess.Popen(["python", "child.py", "2"], stdin=subprocess.PIPE, stdout=subprocess.PIPE) 
out1, err1= c1.communicate("to 1: hit it!") 
print " 1:", repr(out1) 
print "*1:", repr(err1) 
out2, err2= c2.communicate("to 2: ready, set, go!") 
print " 2:", repr(out2) 
print "*2:", repr(err2) 
out1, err1= c1.communicate() 
print " 1:", repr(out1) 
print "*1:", repr(err1) 
out2, err2= c2.communicate() 
print " 2:", repr(out2) 
print "*2:", repr(err2) 
c1.wait() 
c2.wait() 

child.py

import yourDBconnection as dbapi2 

def child1(): 
    print "Child 1 start" 
    conn= dbapi2.connect(...) 
    c1= conn.cursor() 
    conn.begin() # turn off autocommit, start a transaction 
    ra= c1.execute("UPDATE A SET AC1='Achgd' WHERE AC1='AC1-1'") 
    print ra 
    print "Child1", raw_input() 
    rb= c1.execute("UPDATE B SET BC1='Bchgd' WHERE BC1='BC1-1'") 
    print rb 
    c1.close() 
    print "Child 1 finished" 

def child2(): 
    print "Child 2 start" 
    conn= dbapi2.connect(...) 
    c1= conn.cursor() 
    conn.begin() # turn off autocommit, start a transaction 
    rb= c1.execute("UPDATE B SET BC1='Bchgd' WHERE BC1='BC1-1'") 
    print rb 
    print "Child2", raw_input() 
    ra= c1.execute("UPDATE A SET AC1='Achgd' WHERE AC1='AC1-1'") 
    print ta 
    c1.close() 
    print "Child 2 finish" 

try: 
    if sys.argv[1] == "1": 
     child1() 
    else: 
     child2() 
except Exception, e: 
    print repr(e) 

नोट समरूपता। प्रत्येक बच्चा एक संसाधन धारण करना शुरू कर देता है। फिर वे किसी और के संसाधन को प्राप्त करने का प्रयास करते हैं। आप मजेदार के लिए, वास्तव में एक दुष्चक्र के लिए 3 बच्चे और 3 संसाधन कर सकते हैं।

ध्यान दें कि ऐसी स्थिति का सामना करने में कठिनाई जिसमें डेडलॉक होता है। यदि आपके लेनदेन कम हैं - और लगातार - डेडलॉक हासिल करना बहुत मुश्किल है। डेडलॉक की आवश्यकता होती है (ए) लेनदेन जो लंबे समय तक ताले रखता है और (बी) लेनदेन जो एक असंगत क्रम में ताले हासिल करते हैं। मुझे अपने लेन-देन को कम और सुसंगत रखकर डेडलॉक्स को रोकने के लिए सबसे आसान पाया है।

गैर-निर्धारणा को भी ध्यान दें। आप भविष्यवाणी नहीं कर सकते कि कौन सा बच्चा डेडलॉक के साथ मर जाएगा और दूसरे की मृत्यु के बाद जारी रहेगा। दूसरे के लिए आवश्यक संसाधनों को जारी करने के लिए केवल दो में से एक को मरने की जरूरत है। कुछ आरडीबीएमएस का दावा है कि ब्ला ब्ला ब्लाह द्वारा आयोजित संसाधनों की संख्या के आधार पर एक नियम है, लेकिन आम तौर पर, आप कभी नहीं जानते कि पीड़ित को कैसे चुना गया था।

दोनों लिखने के कारण एक विशिष्ट क्रम में होने के कारण, आप उम्मीद करते हैं कि बच्चे 1 पहले मर जाए। हालांकि, आप इसकी गारंटी नहीं दे सकते। यह तब तक डेडलॉक नहीं है जब तक कि बच्चा 2 बच्चे के संसाधनों को प्राप्त करने की कोशिश नहीं करता है - पहले प्राप्त किए गए अनुक्रम का अनुक्रम यह निर्धारित नहीं कर सकता कि कौन मरता है।

यह भी ध्यान दें कि ये प्रक्रियाएं हैं, धागे नहीं। थ्रेड - पायथन जीआईएल की वजह से - अनजाने में सिंक्रनाइज़ किया जा सकता है और अन्य थ्रेड को पकड़ने का मौका देने के लिए time.sleep(0.001) पर कई कॉल की आवश्यकता होगी। प्रक्रियाएं - इसके लिए - थोड़ा सरल हैं क्योंकि वे पूरी तरह से स्वतंत्र हैं।

1

सुनिश्चित नहीं है कि ऊपर या तो सही है या नहीं। की जाँच करें:

स्क्रिप्ट 1:

START TRANSACTION; 
INSERT INTO table <anything you want>; 
SLEEP(5); 
UPDATE table SET field = 'foo'; 
COMMIT; 

स्क्रिप्ट 2:

START TRANSACTION; 
UPDATE table SET field = 'foo'; 
SLEEP(5); 
INSERT INTO table <anything you want>; 
COMMIT; 

निष्पादित

http://www.xaprb.com/blog/2006/08/08/how-to-deliberately-cause-a-deadlock-in-mysql/

2

यहाँ कैसे मैं इसे पीएचपी में क्या करने के लिए कुछ स्यूडोकोड है स्क्रिप्ट 1 और फिर तुरंत Anoth में स्क्रिप्ट 2 निष्पादित करें टर्म टर्मिनल यदि डेटाबेस तालिका में पहले से कुछ डेटा है तो आपको डेडलॉक मिलेगा (दूसरे शब्दों में, दूसरी बार जब आप इसे आजमाते हैं तो यह डेडलॉकिंग शुरू होता है)।

ध्यान दें कि यदि mysql SLEEP() कमांड का सम्मान नहीं करेगा, तो अनुप्रयोग में पाइथन के बराबर का उपयोग करें।

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

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