Готовы тесты. И они меня поразили на столько, что я даже не поверил и многократно перепроверил тестирующие скрипты, но ошибки не нашёл.sverel: пошёл тестить скорость работы с AUTO_COMMIT=1 и без него...
CREATE TABLE `transactions` (
`id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT,
`rand` int(11) UNSIGNED NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB
Где же оно увеличивается?Sluggard: увеличивается время блокировки записей.
Странно, что работая с транзакциями ты не хочешь видеть разницы между пакетным апдейтом строк и реальной практикой. В реальности апдейтится одна строка, а при этом блокируются все текущие операции на чтение, это ты не учел в своем тесте?Вот! В этом и заключается ошибка! Второстепенных операций НЕ БЫВАЕТ! Все инсёрты, апдейты и делиты очень важны! Даже если не нарушают целостность данных, всё равно они важны.pilot911:
если проходят деньги и есть нормальный коммит - это прекрасно и должно отработать независимо от следующих операций, которые могут быть второстепенными... лучше сразу это понять, имхо
Опять ошибка. Когда я внедрял глобальную транзакцию в свой фрейворк, то первым делом написать TDD тесты для транзакций. В этих тестах тестируется запуск паралельного процесса, который обращается к тем записям, которые уже изменены первым процессом. Выглядит это примерно так:Автор оригинала: newARTix В реальности апдейтится одна строка, а при этом блокируются все текущие операции на чтение, это ты не учел в своем тесте?
// Проверяю работоспособность паралельного процесса.
$SQL->query('UPDATE ... SET `fld`=88 WHERE `id`=25');
$testValue = get_file_content('http://domain.com/_tests/helper-transaction.php'); // Скрипт только печатает значение текущего значения `fld` в 25-ой строке.
assertIdentical('88', $testValue);
// Проверяю транзакцию
$SQL->query('BEGIN');
$SQL->query('UPDATE ... SET `fld`=55 WHERE `id`=25');
$testValue = get_file_content('...helper-transaction.php');
assertIdentical('88', $testValue); // Для паралельного процесса новые значение ещё не вступили в силу
$SQL->query('COMMIT');
$testValue = get_file_content('...helper-transaction.php');
assertIdentical('55', $testValue); // А теперь вступили.
// Дальше тоже самое, но с ROLLBACK-ом.
Для этого один юзер должен открыть 2 окна и одновременно засубмитить их. Даже если он так сделает, то мелкие локальные транзакции Вас тоже не спасут. Хотя вероятность одновременного их запуска конечно снизится, но принципиально, Ваш подход ничего не меняет.Автор оригинала: newARTix может это происходить одновременно?
Наверно мне тоже можно поставить подпись "По жизни с TDD".
Вообще транзакции на уровне приложения почти не использую, там где они прям вообще необходимы - предпочитаю процедуры.1. Ну мне это было не очевидно.dimagolov: п.с. вообще странный человек sverel: выполнил на 999 операций начала/коммита транзакции в одном из тестов больше и удивляется, что при этом время исполнения тоже получилось больше.
Ты что-то пытался доказать? Твой пример не в тему. Но даже если его рассматривать. При глобальном коммите длительность блокировки каждой записи - 240 мсек. При AUTOCOMMIT = 1, в среднем, - 26 мсек = время блокировки в 9 раз меньше.Где же оно увеличивается?
Каждый коммит сбрасывает журнал на диск. При частых коммитах скорость вращения диска станет узким местом.Ну мне это было не очевидно.
Выполни: SET GLOBAL innodb_flush_log_at_trx_commit = 0Я даже и представить себе не мог, что будет ТАКАЯ огромная разница: в 100-120 раз быстрее! Для меня это открытие, которое я пока не знаю как объяснить...

)) Конечно можно и дом ка курьях ножка построить, лишь бы желание было 
BEGIN;
SELECT * FROM test;
SAVEPOINT t1
INSERT INTO test SET `id`=1
SAVEPOINT t2
INSERT INTO test SET `id`=2
SELECT * FROM test;
ROLLBACK TO SAVEPOINT t1
INSERT INTO test SET `id`=3
COMMIT;
Протестировал на одной таблице. Первый процесс меняет date_last_visit для 23-его юзера, второй процесс меняет для 58-ого. Итог: оба запроса выполнились одновременно, паралельно. Т.е. один другому не мешает.sverel:
newARTix
Я протестирую как ведёт себя МуСКЛ в такой ситуации и попробую разобраться.