Блокируют ли транзакции MySQL для INSERT таблицы внешних ссылок?
Я пытаюсь выполнить огромную транзакцию в своем Java-приложении и делаю записи с одной вставкой (объем в тысячах) для user_account_entry
таблица, которая имеет ссылку на внешний ключ user
Таблица.
Когда транзакция выполняется, я не могу обновить любой пользовательский объект, для которого принадлежит транзакция, получая LockAcquisitionException
Я использую MySQL InnoDB и использую DEFAULT
уровень изоляции для транзакции, которая переведена на REPEATABLE-READ
уровень для InnoDB, может кто-нибудь пролить свет на блокировку внешнего ключа во время транзакций mysql
2 ответа
Да.
Демонстрация: в одном окне создайте родительские и дочерние таблицы.
mysql1> create table parent (id int primary key, x int );
Query OK, 0 rows affected (0.04 sec)
mysql1> create table child (id int primary key, parentid int,
foreign key(parentid) references parent(id));
Query OK, 0 rows affected (0.03 sec)
Вставьте строку в родительскую таблицу:
mysql1> insert into parent values (1, 1);
Query OK, 1 row affected (0.02 sec)
Запустите транзакцию и добавьте строку в дочернюю таблицу, ссылаясь на родительскую строку:
mysql1> begin;
Query OK, 0 rows affected (0.00 sec)
mysql1> insert into child values (42, 1);
Query OK, 1 row affected (0.00 sec)
Откройте второе окно и попробуйте обновить строку, указанную в parent:
mysql2> update parent set x = 2 where x = 1;
Он зависает, ожидая блокировки, удерживаемой первым сеансом.
Вернитесь к первому окну и подтвердите транзакцию, которая снимает блокировки:
mysql1> commit;
Query OK, 0 rows affected (0.02 sec)
Во втором окне обновление продолжается, и время показывает, что он ждал почти шесть секунд, то есть время, которое потребовалось мне, чтобы вернуться к первому окну для фиксации.
Query OK, 1 row affected (5.92 sec)
Rows matched: 1 Changed: 1 Warnings: 0
У Java есть возможность "пакетной" вставки. Используйте его для вставки до 100 строк одновременно. Это будет работать в 10 раз быстрее, тем самым помогая уменьшить количество проблем.