Предполагая, что вы используете InnoDB в качестве механизма хранения, я бы ожидал такого поведения. Уровень изоляции транзакции по умолчанию для InnoDB: REPEATABLE READ
. Это означает, что когда вы выполняете SELECT
, транзакция получает снимок базы данных в это конкретное время. Снимок будет , а не , включая обновленные данные из других транзакций, которые еще не совершены. Поскольку SELECT
в каждом процессе происходит до того, как кто-либо из них выполнит коммит, каждый из них увидит базу данных в одном и том же состоянии (с num = 1014).
Чтобы получить ожидаемое поведение, вы должны следовать предложению Луиса и выполнить SELECT ... FOR UPDATE
, чтобы заблокировать интересующую вас строку. Для этого измените эту строку
my $r = $schema->resultset('test1')->find({id=>20});
к этому
my $r = $schema->resultset('test1')->find({id=>20}, {for=>'update'});
и повторите тест.
Если вы не знакомы со сложностями транзакций в MySQL, я настоятельно рекомендую вам прочитать раздел в документации о Модель транзакций InnoDB и блокировка . Кроме того, если вы еще этого не сделали, прочитайте Замечания по использованию DBIC относительно транзакций и AutoCommit
также очень внимательно. Поведение txn_
методов, когда AutoCommit
включен или выключен, немного сложнее. Если вы готовы, я бы также предложил прочитать источник. Лично мне нужно было прочитать исходный код, чтобы полностью понять, что делает DBIC, чтобы получить точное поведение, которое я хотел.