Мне нужна помощь в разрешении тупиковой ситуации, с которой я сталкиваюсь.
Ниже приведен тестовый скрипт, имитирующий возникшую у меня проблему, у меня есть таблица тегов, которую по запросу можно вставить / обновитьмного записей, все в одной транзакции.
Я знаю, что тупик возникает из-за того, что множество потоков блокируют одни и те же записи, и я хотел бы получить отзыв о том, как их можно избежать
Я бегу ab -n 100 -c 5 http://localhost/script.php
Это таблица
CREATE TABLE `tags`
(
`id` INT(8) UNSIGNED NOT NULL AUTO_INCREMENT,
`name` VARCHAR(40) COLLATE utf8_unicode_ci DEFAULT NULL,
`weight` INT(8) DEFAULT NULL,
`type` ENUM('1','2','3') COLLATE utf8_unicode_ci DEFAULT NULL,
`modified` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `tag_name` (`name`)
) ENGINE=INNODB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
<?php
function go() {
$db = DB::getInstance();
$db->start_transaction();
$tgs = array('electricity', 'emergency', 'trees', 'New Jersey', 'Canada funnelled');
foreach($tgs as $tg) {
$arr_tags = array(
'name' => $tg,
'weight' => '0',
'type' => TagTable::PRIMARY
);
$tag_instance = new Tag($arr_tags);
$tag_instance->save(true);
// the save method executes a query like the below
// INSERT INTO tags (weight, type, modified, id, name) VALUES(0, "1", NULL, NULL, "$tag") ON DUPLICATE KEY UPDATE weight = weight+1;
}
$db->commit();
}
go();
?>