在树状表中插入批量数据时,MySql InnoDB死锁

时间:2015-02-12 07:49:16

标签: mysql database

尝试使用最新的MySql 5.6.23

获取' 尝试锁定时发现死锁;尝试重新启动交易'当我在下表中插入约5000条记录时。请注意,此错误仅在客户端位置生成。在我们的DEV / TEST环境中,记录顺利插入。

下表显示了父子层次结构(树状)。它还有一些外键constratins和其他索引键(如下所示)

CREATE TABLE `ex_result` (
  `Result_ID` varchar(63) NOT NULL,
  `ParentResult_ID` varchar(63) DEFAULT NULL,
  `StepNumber` int(10) unsigned NOT NULL,
  `Name` varchar(255) NOT NULL,
  `Type` varchar(45) NOT NULL,
  `DB_ID` varchar(63) NOT NULL,
  `Session_ID` varchar(63) NOT NULL,
  `Status` varchar(45) NOT NULL,
  `TotalTime` bigint(20) unsigned NOT NULL,
  `FunctionCall` mediumtext,
  `FunctionResult` mediumtext,
  `ToolTime` bigint(20) unsigned DEFAULT NULL,
  `PluginName` varchar(255) DEFAULT NULL,
  `Screenshot_FID` varchar(63) DEFAULT NULL,
  `IsNegative` tinyint(1) DEFAULT NULL,
  `ContinueOnError` tinyint(1) DEFAULT NULL,
  `WantSnapshot` tinyint(1) DEFAULT NULL,
  `Message` mediumtext,
  `ResultCode` int(10) DEFAULT NULL,
  `Output` mediumtext,
  `InputArguments` mediumtext,
  PRIMARY KEY (`Result_ID`),
  KEY `FK_ex_result_session` (`Session_ID`),
  KEY `FK_ex_result_self` (`ParentResult_ID`),
  KEY `FK_ex_result_Screenshot` (`Screenshot_FID`),
  CONSTRAINT `FK_ex_result_Screenshot` FOREIGN KEY (`Screenshot_FID`) REFERENCES `main_filestore` (`F_ID`) ON DELETE SET NULL ON UPDATE CASCADE,
  CONSTRAINT `FK_ex_result_self` FOREIGN KEY (`ParentResult_ID`) REFERENCES `ex_result` (`Result_ID`) ON DELETE CASCADE ON UPDATE CASCADE,
  CONSTRAINT `FK_ex_result_session` FOREIGN KEY (`Session_ID`) REFERENCES `ex_session` (`Session_ID`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

此代码负责逐行将记录插入上表。

 Private Sub insertRow_inner(ByVal row As DataRow)

    Dim sql = "INSERT INTO ex_result (Result_ID, ParentResult_ID, StepNumber, Name, Type, DB_ID, Session_ID, Status, TotalTime, FunctionCall, FunctionResult, ToolTime, PluginName, Screenshot_FID, IsNegative, ContinueOnError, WantSnapshot, Message, ResultCode, Output, InputArguments) VALUES (@Result_ID, @ParentResult_ID, @StepNumber, @Name, @Type, @DB_ID, @Session_ID, @Status, @TotalTime, @FunctionCall, @FunctionResult, @ToolTime, @PluginName, @Screenshot_FID, @IsNegative, @ContinueOnError, @WantSnapshot, @Message, @ResultCode, @Output, @InputArguments)"

    addParameter("@Result_ID", row("Result_ID"))
    addParameter("@ParentResult_ID", row("ParentResult_ID"))
    addParameter("@StepNumber", row("StepNumber"))
    addParameter("@Name", row("Name"))
    addParameter("@Type", row("Type"))
    addParameter("@DB_ID", row("DB_ID"))
    addParameter("@Session_ID", row("Session_ID"))
    addParameter("@Status", row("Status"))
    addParameter("@TotalTime", row("TotalTime"))
    addParameter("@FunctionCall", row("FunctionCall"))
    addParameter("@FunctionResult", row("FunctionResult"))
    addParameter("@ToolTime", row("ToolTime"))
    addParameter("@PluginName", row("PluginName"))
    addParameter("@Screenshot_FID", row("Screenshot_FID"))
    addParameter("@IsNegative", row("IsNegative"))
    addParameter("@ContinueOnError", row("ContinueOnError"))
    addParameter("@WantSnapshot", row("WantSnapshot"))
    addParameter("@Message", row("Message"))
    addParameter("@ResultCode", row("ResultCode"))
    addParameter("@Output", row("Output"))
    addParameter("@InputArguments", row("InputArguments"))

    ExecuteDML(sql)
End Sub

我在这里观察到,死锁是随机发生的。例如,第10条记录(行)可能会失败,重试时,第15条记录(行)失败。此外,如果它在Transaction下,那么我们无法重试插入(需要重启事务)。如果mainDBM不在Transaction下,那么在第二次重试时插入行(见下面的代码),它就被插入了。

For Each row As DataRow In resultTable.Rows
    Dim trials = 0
    While trials < 5
        trials += 1
        Try
            Me.insertRow_inner(row)
            Exit While
        Catch ex As Exception
            logger.Warning("{0} | - {1}", trials, ex.Message)
        End Try
    End While
Next

知道可能导致死锁的原因吗?

0 个答案:

没有答案