php - Serialization failure: 1213 Deadlock found when trying to get lock; try restarting transaction - Stack Overflow

admin2025-04-22  0

I am facing an issue with a deadlock but I'm failing to understand how both transactions are linked and causing the deadlock.

My log errors are as follows.

Transactiion 1:SQLSTATE[40001]: Serialization failure: 1213 Deadlock found when trying to get lock; The SQL being executed was:

UPDATE job_instruction ji\n                
INNER JOIN ji_temp2 ON ji.id = ji_temp2.id\n                
SET ji.job_instruction_group_id = ji_temp2.job_instruction_group_id"

Transaction 2: SQLSTATE[HY000]: General error: 1205 Lock wait timeout exceeded;

UPDATE inventory SET                                    
on_hand_quantity = ifnull(on_hand_quantity,0) + (1)\n
,allocated_quantity = ifnull(allocated_quantity,0) + (1)\n                                    
,in_transit_quantity = ifnull(in_transit_quantity,0) + (-1)\n                                    
,suspended_quantity = ifnull(suspended_quantity,0) + (0)\n                                    
,updated_at = 1737630861\n                                    
WHERE id = 2474210

The php code for transaction 1:

\Yii::$app->db->createCommand()->batchInsert(
                    JobInstructionGroup::tableName(),
                    ['job_id', 'unit_of_measure', 'inventory_id', 'units', 'quantity', 'out_bound_status_flow_id', 'created_at', 'updated_at', 'created_by', 'updated_by'],
                    $job_instruction_groups
                )->execute();
     foreach ($processedCombinations as $data) {
                if ($data['count'] > 1) {
                    $job_instruction_groups[] = [
                        'job_id' => $data['job_id'],
                        'unit_of_measure' => $data['unit_of_measure'],
                        'inventory_id' => $data['inventory_id'],
                        'units' => $data['units'],
                        'quantity' => $data['quantity'],
                        'out_bound_status_flow_id' => $data['out_bound_status_flow_id'],
                        'created_at' => time(),
                        'updated_at' => time(),
                        'created_by' => \Yii::$app->user->identity->id,
                        'updated_by' => \Yii::$app->user->identity->id,
                    ];
                    $jobIds[] = $data['job_id'];
                    // $inventoryIds[] = $data['inventory_id'];
                    // $outBoundStatusFlowIds[] = $data['out_bound_status_flow_id'];

                }
            }

\Yii::$app->db->createCommand("CREATE TEMPORARY TABLE ji_temp1 AS SELECT * FROM job_instruction WHERE job_instruction.job_id IN (".implode(',',array_unique($jobIds)).")")->execute();
                \Yii::$app->db->createCommand("
                
                CREATE TEMPORARY TABLE ji_temp2 AS SELECT ji_temp1.id, 
                    job_instruction_group.id AS job_instruction_group_id 
                from ji_temp1
                
                INNER JOIN shipment_detail_child 
                ON shipment_detail_child.job_instruction_id = ji_temp1.id
                
                INNER JOIN shipment_detail 
                ON shipment_detail.id = shipment_detail_child.shipment_detail_id
                
                INNER JOIN shipment_header 
                ON shipment_header.id = shipment_detail.shipment_header_id
                
                INNER JOIN job_instruction_group 
                ON job_instruction_group.job_id = ji_temp1.job_id 
                
                AND job_instruction_group.inventory_id = ji_temp1.inventory_id 
                AND job_instruction_group.out_bound_status_flow_id = shipment_header.out_bound_status_flow_id")->execute();
                
                \Yii::$app->db->createCommand("
                UPDATE job_instruction ji
                INNER JOIN ji_temp2 ON ji.id = ji_temp2.id
                SET ji.job_instruction_group_id = ji_temp2.job_instruction_group_id")->execute();

The php code for transaction 2:

Yii::$app->db->createCommand('UPDATE inventory SET 
                                        on_hand_quantity = ifnull(on_hand_quantity,0) + (:on_hand_quantity)
                                        ,allocated_quantity = ifnull(allocated_quantity,0) + (:allocated_quantity)
                                        ,in_transit_quantity = ifnull(in_transit_quantity,0) + (:in_transit_quantity)
                                        ,suspended_quantity = ifnull(suspended_quantity,0) + (:suspended_quantity)
                                        ,updated_at = :updated_at
                                        WHERE id = :id',
                                        [ ':id' => $id, 
                                          ':on_hand_quantity'=>$on_hand_quantity,
                                          ':allocated_quantity'=>$allocated_quantity,
                                          ':suspended_quantity'=>$suspended_quantity,
                                          ':in_transit_quantity'=>$in_transit_quantity,
                                          ':updated_at'=>$time])->execute();

My transaction 2 is specific to a where clause and in transaction 1 I have not used any inventory table(Although shipment child and shipment_header does have the relation) so could that be causing a deadlock ? Or another case that I thought is maybe the both transaction aren't related to a specific deadlock but the time is same tho.

A suggestion to optimize the query would also be appreciated if that can resolve the case.

转载请注明原文地址:http://conceptsofalgorithm.com/Algorithm/1745305136a295493.html

最新回复(0)