Как я могу Вызвать Мертвую блокировку в MySQL для тестирования

Сборка | Build Project показывает все ошибки в проекте.

8
задан Greg 10 November 2008 в 15:12
поделиться

4 ответа

можно всегда выполнять имя таблицы ТАБЛИЦЫ БЛОКИРОВКИ от другой сессии (mysql CLI, например). Это могло бы добиться цели.

Это останется заблокированным, пока Вы не выпустите его или разъедините сессию.

1
ответ дан 5 December 2019 в 22:21
поделиться

Я не familar с Python, так извините мой неправильный язык, Если я говорю, что эта несправедливость..., но открывает две сессии (в отдельных окнах, или от отдельных процессов Python - от отдельных полей работал бы...), Затем...

. На сессии A:

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

. Затем на сессии B:

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

. Затем вернитесь к сессии A

  Insert TableB() Values () ...

Вы получите мертвую блокировку...

1
ответ дан 5 December 2019 в 22:21
поделиться

Вы хотите что-то вдоль следующих строк.

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 ресурса для действительно порочного круга.

Обратите внимание, что трудность при изобретении ситуации, в которой происходит мертвая блокировка. Если Ваши транзакции коротки - и последовательны - мертвой блокировки очень трудно достигнуть. Мертвая блокировка требует (a) транзакции, которые содержат блокировки в течение долгого времени И (b) транзакций, которые получают, привязывает непоследовательный порядок. Я нашел самым легким предотвратить мертвые блокировки путем сохранения моих транзакций короткими и последовательными.

Также отметьте недетерминизм. Вы не можете предсказать, какой ребенок умрет с мертвой блокировкой и который продолжится после другого умер. Только один из этих двух должен умереть для высвобождения необходимых средств на другой. Заявление некоторого RDBMS, что существует правило на основе количества ресурсов, сохраненных и тому подобное, но в целом, Вы никогда не будете знать, как жертва была выбрана.

Из-за двух записей, находящихся в определенном порядке, Вы сортируете, ожидают, что ребенок 1 умрет сначала. Однако Вы не можете гарантировать это. Это не мертвая блокировка до ребенка 2 попытки получить ребенка 1 ресурсы - последовательность того, кто получил, сначала может не определить, кто умирает.

Также обратите внимание, что это процессы, не потоки. Потоки - из-за GIL Python - могли бы непреднамеренно синхронизироваться и потребуют большого количества вызовов к time.sleep( 0.001 ) дать другому потоку шанс нагнать. Процессы - для этого - немного более просты, потому что они полностью независимы.

1
ответ дан 5 December 2019 в 22:21
поделиться

Не уверен, правильно ли что-то из вышеперечисленного. Посмотрите это:

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

1
ответ дан 5 December 2019 в 22:21
поделиться
Другие вопросы по тегам:

Похожие вопросы: