出现了死锁问题?

production.ERROR: SQLSTATE[40001]: Serialization failure: 1213 Deadlock found when trying to get lock; try restarting transaction (SQL: update `product_skus` set `stock` = `stock` - 1, `updated_at` = 2019-02-03 09:33:41 where `id` = 112 and `stock` >= 1) {"userId":30,"email":"ducimus.velit@example.org","exception":"[object] (Illuminate\\Database\\QueryException(code: 40001): SQLSTATE[40001]: Serialization failure: 1213 Deadlock found when trying to get lock; try restarting transaction (SQL: update `product_skus` set `stock` = `stock` - 1, `updated_at` = 2019-02-03 09:33:41 where `id` = 112 and `stock` >= 1) at /var/www/laravel-shop/releases/7/vendor/laravel/framework/src/Illuminate/Database/Connection.php:664, Doctrine\\DBAL\\Driver\\PDOException(code: 40001): SQLSTATE[40001]: Serialization failure: 1213 Deadlock found when trying to get lock; try restarting transaction at /var/www/laravel-shop/releases/7/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOStatement.php:119, PDOException(code: 40001): SQLSTATE[40001]: Serialization failure: 1213 Deadlock found when trying to get lock; try restarting transaction at /var/www/laravel-shop/releases/7/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOStatement.php:117)
[stacktrace]
#0 /var/www/laravel-shop/releases/7/vendor/laravel/framework/src/Illuminate/Database/Connection.php(624): Illuminate\\Database\\Connection->runQueryCallback('update `product...', Array, Object(Closure))
#1 /var/www/laravel-shop/releases/7/vendor/laravel/framework/src/Illuminate/Database/Connection.php(490): Illuminate\\Database\\Connection->run('update `product...', Array, Object(Closure))
#2 /var/www/laravel-shop/releases/7/vendor/laravel/framework/src/Illuminate/Database/Connection.php(423): Illuminate\\Database\\Connection->affectingStatement('update `product...', Array)
#3 /var/www/laravel-shop/releases/7/vendor/laravel/framework/src/Illuminate/Database/Query/Builder.php(2659): Illuminate\\Database\\Connection->update('update `product...', Array)
#4 /var/www/laravel-shop/releases/7/vendor/laravel/framework/src/Illuminate/Database/Query/Builder.php(2718): Illuminate\\Database\\Query\\Builder->update(Array)
#5 /var/www/laravel-shop/releases/7/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Builder.php(844): Illuminate\\Database\\Query\\Builder->decrement('stock', 1, Array)
#6 /var/www/laravel-shop/releases/7/app/Models/ProductSku.php(28): Illuminate\\Database\\Eloquent\\Builder->decrement('stock', 1)
#7 /var/www/laravel-shop/releases/7/app/Services/OrderService.php(174): App\\Models\\ProductSku->decreaseStock(1)
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
leo
最佳答案

if ($sku->decreaseStock(1) <= 0) {
    throw new InvalidRequestException('该商品库存不足');
}

移到事务的最开头再试试看?这里当时没有仔细看日志遗漏了。

5年前 评论
xiao 4年前
讨论数量: 4
leo

登录到数据库服务器,然后执行 SQL:

mysql > show engine innodb status;

然后找到 LATEST DETECTED DEADLOCK,把下面的信息截图发上来看看

5年前 评论

@leo


------------------------
LATEST DETECTED DEADLOCK
------------------------
2019-02-10 15:49:21 0x7f4804703700
*** (1) TRANSACTION:
TRANSACTION 10462, ACTIVE 0 sec starting index read
mysql tables in use 1, locked 1
LOCK WAIT 11 lock struct(s), heap size 1136, 5 row lock(s), undo log entries 2
MySQL thread id 74114, OS thread handle 139947288033024, query id 1200176 172.17.182.226 laravel-shop updating
update `product_skus` set `stock` = `stock` - 1, `updated_at` = ? where `id` = ? and `stock` >= ?
*** (1) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 48 page no 3 n bits 184 index PRIMARY of table `laravel-shop`.`product_skus` trx id 10462 lock_mode X locks rec but not gap waiting
Record lock, heap no 113 PHYSICAL RECORD: n_fields 10; compact format; info bits 0
 0: len 4; hex 00000070; asc    p;;
 1: len 6; hex 0000000028db; asc     ( ;;
 2: len 7; hex 32000001c00c47; asc 2     G;;
 3: len 15; hex e7a792e69d80206950686f6e652058; asc        iPhone X;;
 4: len 15; hex e7a792e69d80206950686f6e652058; asc        iPhone X;;
 5: len 5; hex 80001e7800; asc    x ;;
 6: len 4; hex 0000001b; asc     ;;
 7: len 4; hex 00000025; asc    %;;
 8: len 4; hex 5c4ff239; asc \O 9;;
 9: len 4; hex 5c5fd781; asc \_  ;;

*** (2) TRANSACTION:
TRANSACTION 10461, ACTIVE 0 sec starting index read
mysql tables in use 1, locked 1
11 lock struct(s), heap size 1136, 5 row lock(s), undo log entries 2
MySQL thread id 74109, OS thread handle 139947288835840, query id 1200179 172.17.182.227 laravel-shop updating
update `product_skus` set `stock` = `stock` - 1, `updated_at` = ? where `id` = ? and `stock` >= ?
*** (2) HOLDS THE LOCK(S):
RECORD LOCKS space id 48 page no 3 n bits 184 index PRIMARY of table `laravel-shop`.`product_skus` trx id 10461 lock mode S locks rec but not gap
Record lock, heap no 113 PHYSICAL RECORD: n_fields 10; compact format; info bits 0
 0: len 4; hex 00000070; asc    p;;
 1: len 6; hex 0000000028db; asc     ( ;;
 2: len 7; hex 32000001c00c47; asc 2     G;;
 3: len 15; hex e7a792e69d80206950686f6e652058; asc        iPhone X;;
 4: len 15; hex e7a792e69d80206950686f6e652058; asc        iPhone X;;
 5: len 5; hex 80001e7800; asc    x ;;
 6: len 4; hex 0000001b; asc     ;;
 7: len 4; hex 00000025; asc    %;;
 8: len 4; hex 5c4ff239; asc \O 9;;
 9: len 4; hex 5c5fd781; asc \_  ;;

*** (2) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 48 page no 3 n bits 184 index PRIMARY of table `laravel-shop`.`product_skus` trx id 10461 lock_mode X locks rec but not gap waiting
Record lock, heap no 113 PHYSICAL RECORD: n_fields 10; compact format; info bits 0
 0: len 4; hex 00000070; asc    p;;
 1: len 6; hex 0000000028db; asc     ( ;;
 2: len 7; hex 32000001c00c47; asc 2     G;;
 3: len 15; hex e7a792e69d80206950686f6e652058; asc        iPhone X;;
 4: len 15; hex e7a792e69d80206950686f6e652058; asc        iPhone X;;
 5: len 5; hex 80001e7800; asc    x ;;
 6: len 4; hex 0000001b; asc     ;;
 7: len 4; hex 00000025; asc    %;;
 8: len 4; hex 5c4ff239; asc \O 9;;
 9: len 4; hex 5c5fd781; asc \_  ;;

*** WE ROLL BACK TRANSACTION (2)
------------
TRANSACTIONS
------------
Trx id counter 10487
Purge done for trx's n:o 
5年前 评论
leo

if ($sku->decreaseStock(1) <= 0) {
    throw new InvalidRequestException('该商品库存不足');
}

移到事务的最开头再试试看?这里当时没有仔细看日志遗漏了。

5年前 评论
xiao 4年前

@leo 可以,不会出现死锁问题了

5年前 评论
xiao 4年前
w594533 (作者) (楼主) 4年前
xiao 4年前
xiao 4年前

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!