Mysql

為什麼事務阻塞 MySQL 中的簡單插入?

  • May 11, 2021

交易查詢

   mysqli_begin_transaction($conn);
   $sql = "UPDATE foldertable SET trashed = 1 WHERE serverToken = (SELECT serverToken from servertoken where userToken = ? limit 1) and 
   
   (folderId = ?
   or 
   RootFolderPath LIKE 
               CONCAT (
                   (SELECT RootFolderPath FROM foldertable WHERE serverToken = (SELECT serverToken from servertoken where userToken = ? ) AND folderid = ? limit 1)
                   ,'/'
                   , ?
                   ,'%'

               )
   )";
   $stmt =  mysqli_stmt_init($conn);
   mysqli_stmt_prepare($stmt, $sql);
   mysqli_stmt_bind_param($stmt, "sisii", $data["userToken"], $id, $data["userToken"], $id, $id);
   if (!mysqli_stmt_execute($stmt)) {
       echo mysqli_stmt_error($stmt);
       $serverError = true;
       return;
   }
   // echo "\n\n affected rows " . mysqli_affected_rows($conn);
   if (mysqli_affected_rows($conn) > 0) {
       sleep(15);
       // Insert into bin folder
       $sql = "INSERT INTO binfolder (serverToken , folderId) value ( (SELECT serverToken from servertoken where userToken = ? limit 1) , ?)";
       $stmt =  mysqli_stmt_init($conn);
       mysqli_stmt_prepare($stmt, $sql);
       mysqli_stmt_bind_param($stmt, "si", $data["userToken"], $id);
       if (!mysqli_stmt_execute($stmt)) {
           echo mysqli_stmt_error($stmt);
           $serverError = true;
           return;
       }
       if (mysqli_affected_rows($conn) > 0) {
           $success = true;
           mysqli_commit($conn);
       }

   }

插入查詢

INSERT INTO foldertable(serverToken) SELECT (123456) 

問題

如果在事務開始後執行插入查詢,但插入不必等待事務完成。因為事務上的更新查詢確實鎖定了插入查詢所涉及的行。

我想要的

如果插入查詢不包含serverToken插入查詢所需的內容,則插入查詢將立即執行。

先感謝您。

文件夾表結構

對於事務阻塞,第一道防線是加快查詢速度。雖然這並不能完全消除阻塞/延遲/死鎖的可能性,但它通常會使情況更容易忍受。

重新LIMIT 1——只有1個嗎?如果是這樣,為什麼不做一個JOIN. 或者可能不止一個?如果有,是哪一個?也就是說,你不需要一個ORDER BY?

servertoken需要INDEX(userToken, serverToken)

一個INSERT ... ON DUPLICATE KEY UPDATE ...就足以滿足您冗長的查詢集嗎?如果是這樣,它可能會快很多。

OR在長查詢中看到一個。這可能會阻止索引的使用。(我不太了解查詢的意圖,無法提出替代方案。)

“RootFolderPath LIKE CONCAT (…” - 這聞起來像是應該重新設計的東西。考慮將路徑部分放在單獨的列中?或其他東西。

是嗎?folderId_PRIMARY KEY``folderTable

請為每個相關表格提供SHOW CREATE TABLE(作為文本,而不是圖像)。

引用自:https://dba.stackexchange.com/questions/291347