由于“超出锁定等待超时;尝试重新启动事务”,事务失败

时间:2011-04-19 14:53:21

标签: java mysql

尝试更新某个表时,它会失败,但“超出锁定等待超时;尝试重新启动事务”除外。 一些信息:我有两个表,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;
}

2 个答案:

答案 0 :(得分:3)

好的,我弄清楚问题是什么 - 在updateAllFields中(由于某些奇怪的原因,我没有在这里显示)我获得了一个新的连接,所以两个事务混合了。 谢谢你的帮助!

答案 1 :(得分:0)

看看innodb_lock_wait_timeout变量。它是 - InnoDB事务在回滚之前可能等待锁定的超时秒数。默认值为50秒,您可以增加此值;但我认为最好重写循环插入代码或优化某些东西。

作为变体 - 尝试在事务中运行较少的insert语句。 要加快交易速度,您可以使用多个插入内容,例如 - 'INSERT INTO table1(column1,column2)VALUES(1,'text1'),(2,'text2')...;'