长mysql事务(~30秒)只有插入查询是一个问题吗?(InnoDB)


Are long mysql transactions (~30 seconds) with only insert queries an issue? (InnoDB)

我正在编写一个PHP脚本,用于处理文件并将有关文件的信息插入到数据库中。

具体来说,脚本处理一些信息,然后开始一个事务并将其插入到表中。然后,我使用lastinsertid来获得刚刚插入行的ID,并使用该ID来处理相关文件。当处理完成时(大约需要2-30秒),我在其他表中执行更多的插入操作,并在检查文件处理成功后完成事务。

所以基本上概要是这样的:

START TRANSACTION
INSERT DATA INTO TABLE 1
PROCESS FILE USING INSERT ID (takes 2-30 seconds)
INSERT DATA INTO TABLE 2
INSERT DATA INTO TABLE 3
INSERT DATA INTO TABLE 4
//VERIFY FILE PROCESSING    
  if ($file_process == true){   
COMMIT   
}   
else{   
ROLLBACK   
}   

我知道由于长时间持有锁的问题,应该避免长事务,但是如果事务只使用插入怎么办?由于插入只锁定正在插入的行,这仍然是一个问题吗?

谁能给我解释一下这种情况下可能出现的"陷阱"?我很确定,如果一个会话的进程花费了很长时间,而另一个会话开始了他们自己的进程,session 1将不会阻塞session 2,因为进程只处理插入。如果session 1失败并且必须回滚,它将不会对session 2产生任何影响(除了在数据库中,自动递增的主id会有一个间隙,但这无关紧要)

由于插入只锁定正在插入的行,这仍然是一个问题吗?

不总是正确的。如果在details表中插入记录,主记录也会被锁定。如果您有许多关系,那么很难知道究竟锁定了什么,这反过来又可能导致死锁。

如果PHP脚本中数据库插入的运行时间达到30秒,那么您可能会遇到PHP的最大执行时间上限。

您可以通过编程方式更改时间限制来缓解这种情况。

http://php.net/manual/en/function.set-time-limit.php

你可以修改你的php.ini文件来改变默认值。如果这成为一个问题,我建议只对数据库调用进行修改,这样您就不会让与数据库无关的失控脚本阻塞服务器的资源。

如果您不确定在那里使用事务,我建议您在那里使用new_added_row额外列,如果出现问题,您只需删除new_added_row=1列以回滚您的事务。您仍然会获得insert_id,而不使用事务,并且能够回滚更改。如果多个用户将异步执行此操作,则可以考虑使用' session_key extra列来防止删除其他人的插入。