У нас были периодические ошибки блокировки (примерно 1-2 в день из ~ 250).
При оформлении заказа мы получаем все данные о пользователях, сохраняем заказ, обрабатываем любые платежи, и затем обновите заказ. Я думаю, что это может быть вторичное обновление, которое вызывает его.
Пример нашего кода (не совсем то же самое, но достаточно близко):
DB::transaction(function () use ($paymentMethod, $singleUseTokenId, $requiresPayment, $chargeAccount) {
// create order locally
$order = Order::create([
'blah' => $data['blah'],
]);
// handle payment
$this->handlePayment();
// update order with new status (with a secondary transaction for safety)
DB::transaction(function () use ($order) {
$order->update([
'status' => 'new status',
]);
}, 5);
}, 5); // Retry transaction 5 times - this reduced the lock timeout errors a lot
И периодически возникающая ошибка, которую мы получаем ( фактические значения удалены):
SQLSTATE[HY000]: General error: 1205 Lock wait timeout exceeded; try restarting transaction (SQL: insert into `orders` (`user_id`, `customer_uuid`, `type_uuid`, `status_uuid`, `po_number`, `order_details`, `cart_identifier`, `cart_content`, `cart_sub_total`, `cart_tax`, `cart_grand_total`, `payment_type_uuid`, `shipping_address`, `uuid`, `updated_at`, `created_at`)
Я много читал об этом, и некоторые люди говорят, что увеличение времени ожидания (кажется обходным решением), оптимизация c блокировка (я думал, транзакции уже делают это), и другие вещи.
Из того, что я могу сказать из крошек базы данных, создание заказа иногда занимает много времени (например, видел один в 3 с, другой в 23 с по какой-то причине, как правило, это вставка 50 мс), а затем другой что-то происходит, и он пытается обновить заказ, но строка все еще заблокирована из create ().
Примечания:
- У нас есть 4 внешних ключа в таблице заказов (customer uuid , пользователь uuid, тип заказа uuid, статус заказа uuid) - я чувствую, что это может вызывать проблемы.
- Некоторые красноречивые создания берут 3 секунды, другие 23 (только проверенные проблемы). Для большинства заказов максимальный запрос составляет 500 мс, поэтому это выбросы.
Есть предложения?
Решение: первичного ключа в заказах нет. Очень глупая ошибка. Заставил InnoDB создать 6-байтовый ключ для индекса. И заблокируйте от последовательной вставки, затем обновите ..