簡體   English   中英

由於“超過了鎖定等待超時,導致事務失敗; 嘗試重新開始交易”

[英]Transactions fails due to “Lock wait timeout exceeded; try restarting transaction”

嘗試更新某個表時,它失敗,但以下情況除外:“超出了鎖定等待超時;嘗試重新啟動事務”。 一些信息:我有兩個表,profile和profile_units。 ID是概要文件表的主鍵,ID是profile_units中的主鍵的一部分,也是概要文件中ID的外鍵。 我調用saveProfileChanges時,updateAllFields方法成功,但是addStmt.executeUpdate();成功。 在handleActivityUnitsChanges中失敗,但出現上述異常。 我使用MySQL v5.0作為數據庫。 我究竟做錯了什么?

我嘗試執行以下代碼:

    public static Profile saveProfileChanges(Profile profile, List unitsToAdd)
        throws Exception
{
    Connection con = null;
    try
    {
        con = ConnectionManager.getConnection();

        updateAllFields(con, profile);

        handleActivityUnitsChanges(con, profile, unitsToAdd);

        con.commit();
        return profile;
    }
    finally
    {
        ConnectionManager.closeConnection(con);
    }
}

private static void handleActivityUnitsChanges(Connection con, Profile profile, List<ActivityUnit> unitsToAdd) throws Exception
{
    PreparedStatement addStmt = null;

    try
    {
        for (ActivityUnit currentUnitToAdd : unitsToAdd)
        {
            String sqlStatement = "insert into profile_units (ID, ActivityUnit) values (?, ?)";
            addStmt = con.prepareStatement(sqlStatement);

            addStmt.setLong(1, profile.getId());
            addStmt.setLong(2, currentUnitToAdd.getId());

            System.out.println(sqlStatement);

            addStmt.executeUpdate();
            addStmt.close();
        }
    }
    catch (Exception e)
    {
        con.rollback();
        throw e;
    }
    finally
    {
        ConnectionManager.closeStatement(addStmt);
    }
}

public static Connection getConnection() throws Exception
{
    Class.forName("com.mysql.jdbc.Driver").newInstance();
    Connection con = DriverManager.getConnection("jdbc:mysql:///someproject", "a", "a");

    con.setAutoCommit(false);

    return con;
}

好的,我發現了問題所在-在updateAllFields中(出於某種奇怪的原因,我沒有在此處顯示),我獲得了一個新的連接,因此這兩個事務混合在一起了。 感謝任何人的幫助!

看一下innodb_lock_wait_timeout變量。 這是-InnoDB事務在回滾之前可能等待鎖定的超時時間(以秒為單位) 默認值為50秒,您可以增加此值; 但我認為最好重寫循環插入代碼或進行優化。

作為一種變體-嘗試在事務中運行較少的插入語句。 為了加快交易,您可以使用多個插入,例如-'INSERT INTO table1(column1,column2)VALUES(1,'text1'),(2,'text2')...;'

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM