2011-08-15 6 views
2

私はこのテーブルを持っている:なぜこれらの2つのSQL文がデッドロック・エラーを引き起こしましたか?

CREATE TABLE `notify` (
    `id` int(11) NOT NULL auto_increment, 
    `notify_type` char(1) NOT NULL, 
    `notify_id` int(10) unsigned NOT NULL, 
    `create_time` timestamp NOT NULL default '0000-00-00 00:00:00', 
    `user` int(10) unsigned NOT NULL, 
    `update_time` timestamp NOT NULL default '0000-00-00 00:00:00', 
    PRIMARY KEY (`id`), 
    UNIQUE KEY `notify_id` (`notify_id`,`notify_type`,`user`), 
    KEY `Index_time` (`create_time`), 
    KEY `user_update` (`user`,`update_time`) 
) 

と2つのSQLクエリ連続して実行し、それはしばしば

OperationalError: (1213, 'Deadlock found when trying to get lock; try restarting transaction')

が生じ一緒

if user_id: 
    insert into notify (notify_type,notify_id,user,create_time) 
    values (%s,%s,%s,CURRENT_TIMESTAMP) 
    ON DUPLICATE KEY UPDATE update_time=update_time, (type, id, user_id) 

    update notify set update_time=NOW() where notify_type = %s 
    and notify_id =%s and user!=%s,(type, id, user_id) 
else: 
    update reply_notify set update_time=NOW() where notify_type = %s 
    and notify_id =%s, (type, id) 
commit() 

を犯したが誰も私がなぜ把握助けることができるだろうそれは?私はMySQLのドキュメントを調べましたが、ON DUPLICATE KEY UPDATE節に関連するものはないのですが、それでもわかりません。

他のコードがelseブランチに実行されている間に、それらの2つのトランザクションがデッドロックされていることがありますか?

+1

"2つのSQL文" – Will

+0

はいを​​投稿してください。私はテーブルの下に投稿しました – alexband

+0

update_timeをupdate_timeカラムの既存の値に割り当てるので、 'ON DUPLICATE KEY'節は何もしません。これとは別に、なぜ1つのトランザクションで同じ行を更新する2つのクエリを送信しようとしていますか? –

答えて

1

MySQL's docによれば、クエリは正常に見えます。しかし、関連するかもしれないa bugがあります。

テーブルで使用されているエンジンを切り替えることができます.5.0ではBDB (Berkeley DB)を試すことができますが、現在はサポートされていません。それ以外の場合はMyISAMが最適です。

また、LOCK TABLES ... UNLOCK TABLESを挿入して問題を解決することもできます。 これを失敗すると、ロックテーブルをブロック全体(更新を含む)に配置して、実際にこの部分が問題になっているかどうかを確認できます。

通常、テーブルロックはパフォーマンスにはあまり良くなく、MyISAMは頻繁に更新されるようには設計されていませんが、あまり選択肢がない可能性があります。


lock tables notify write; 
insert into notify (notify_type,notify_id,user,create_time) 
values (%s,%s,%s,CURRENT_TIMESTAMP) 
ON DUPLICATE KEY UPDATE update_time=update_time, (type, id, user_id); 
unlock tables; 
関連する問題