2013-02-16 2 views
1

Время от времени я получаю ошибку mysql. ОшибкаПочему тупик mysql здесь?

Deadlock found when trying to get lock; try restarting transaction 

запрос

var res = cn.Execute("insert ignore into 
    Post(desc, item_id, user, flags) 
    select @desc, @itemid, @userid, 0", 
    new { desc, itemid, userid }); 

Как на земле может этот запрос причиной этого? Когда googling я видел что-то о том, как запросы, которые занимают длинные строки блокировки и вызывают эту проблему, но для этой вставки не нужно прикасаться ни одной строки.

+0

Вы используете myisam или innodb? Кроме того, вам нужно знать, что было выполнено ранее. AFAIK тупик никогда не приходит из одного запроса. – Sebas

+1

Есть ли у вас какие-либо другие запросы в одном соединении? –

+0

@Sebas: Я не уверен, у меня есть 4 экземпляра. Это линия, которая имела проблему. Даже если другие строки были заблокированы, я не знаю, как это произойдет. Я подозреваю, что другой клиент сделал то же самое, что и я начал их в одно и то же время, и каждое состояние длилось несколько минут. – 2013-02-16 19:17:46

ответ

3

Замки вызваны inter-transaction заказ и блокировка приобретений. Как правило, для каждого соединения есть одна активная транзакция (хотя разные базы данных могут работать по-разному). Так что только в случае несколько подключений и, следовательно, несколько перекрывающихся транзакций, что могут возникнуть взаимоблокировки. Единственное соединение/транзакция не может затормозить, потому что нет блокировки, которую он не может получить: у нее есть или она может ее получить.

Вставной тупик может be caused by a unique constraint - так что проверьте наличие уникального ключа в качестве виновника. Другими причинами могут быть блокировки для выборочных заявлений «для обновления» и т. Д.

Кроме того, убедитесь, что все транзакции завершены немедленно (завершено или откат) после операций, требующих их. Если транзакция не закрыта своевременно, это может привести к такому тупиковому поведению тривиально. Хотя "autocommit" обычно обрабатывает это, его можно изменить, и на него нельзя положиться: я рекомендую использовать ручную транзакцию вручную.

См. Mysql deadlock explanation needed и How to Cope with Deadlocks для получения дополнительной информации. В этом случае, вероятно, достаточно «просто повторить попытку».

+0

Мои транзакции продолжаются некоторое время, потому что он несколько раз попадает на сервер, поэтому он может принимать> 200 мс. Я думаю, это имеет смысл, хотя я не понимаю, почему его тупик, когда его тот же запрос. Возможно, это связано с тем, что другие транзакции не видны. – 2013-02-16 20:07:34

+0

@ acidzombie24 Если это * только *, который вставляет запрос, то я подозреваю, что это GAP, как описано в связанной статье. – 2013-02-16 20:08:24