【问题标题】:getting lock wait timout when calling mysql proc from java从java调用mysql proc时获得锁等待超时
【发布时间】:2015-10-17 17:04:30
【问题描述】:

我在下面有这个过程:

CREATE PROCEDURE updatepath()
BEGIN
declare cnt, n int;
    update foo a set a.path=a.name where a.parent_id is null;
    select count(*) into cnt from foo where path is null;
    while cnt > 0 do
        update foo a, foo b set a.path = concat(b.path, '/', a.name)  where b.path is not null and a.parent_id = b.id;
        select row_count() into cnt;
    end while;
END;
;;

当我从 mysql 工作台调用这个过程时,如下所示:

调用 updatePath(); 它在几毫秒内成功执行。 但是,当我从 java 程序运行相同的代码时,会花费大量时间,最终我不得不终止 java 进程。 调用proc的代码如下:

{
            jdbcTemplate.execute(
                    new CallableStatementCreator() {
                        public CallableStatement createCallableStatement(Connection con) throws SQLException {
                            CallableStatement cs = con.prepareCall("{call updatePath()}");  
                            return cs;
                        }
                    },
                    new CallableStatementCallback() {
                        public Object doInCallableStatement(CallableStatement cs) throws SQLException {
                            cs.execute();
                            return null;
                        }
                    }
            );        
        }

上述方法在单独的事务中运行。当我在一段时间后终止事务时,我看到它正在等待锁定。 在执行 show engine innodb status 时,我得到以下信息:

---TRANSACTION 4186138, ACTIVE 532 sec fetching rows mysql tables in use 2, locked 2 37 lock struct(s), heap size 6544, 2437 row lock(s), 撤消日志条目 307157 MySQL 线程 id 14,OS 线程句柄 0x2b38, 查询id 461758 localhost 127.0.0.1 root 发送数据 更新 foo a, foo b set a.path = concat(b.path, '/', a.name) 其中 b.path 不为空且 a.parent_id = b.id;

【问题讨论】:

    标签: java mysql spring transactions locking


    【解决方案1】:

    问题似乎是循环中更新后的“select row_count() into cnt”语句。这个row_count负责维护循环。 在我的情况下,while 处于无限循环中,因为更新语句在所有记录更新后始终为真。 当我在 mysql 工作台上单独运行查询时。我看到修改了 0 行,找到了 6 行。从工作台运行 proc 时,row_count 似乎是从修改后的行中填充的,但是当我从 java 程序运行它时,它似乎正在拾取找到的行。 通过将循环中的查询修改为以下,我可以从工作台和 java 应用程序中运行它:

    update foo a, foo b set a.path = concat(b.path, '/', a.name)  where b.path is not null and a.parent_id = b.id **and a.path is null** ;
    

    【讨论】:

      猜你喜欢
      • 2011-01-07
      • 2017-12-26
      • 2021-10-15
      • 2015-09-20
      • 2011-12-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-24
      相关资源
      最近更新 更多