从 java 调用 mysql proc 时获取锁定等待超时
getting lock wait timout when calling mysql proc from java
我有以下过程:
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 workbench 调用此过程时,如下所示:
调用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;
}
}
);
}
上面的方法是 运行在一个单独的 transaction.When 中,我在一段时间后终止了事务,我看到它正在等待锁。
在执行 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),
undo log entries 307157 MySQL thread id 14, OS thread handle 0x2b38,
query id 461758 localhost 127.0.0.1 root Sending data
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;
问题好像是在loop.This更新后的"select row_count() into cnt"语句row_count负责维护循环。
在我的例子中,while 进入无限循环,因为更新所有记录后更新语句始终为真。
当我 运行 mysql 工作台上的查询 separately.I 看到修改了 0 行,6 行 found.While 运行ning 来自 workbench ,row_count 似乎是从修改后的行中填充的,但是当我从 java 程序中 运行 它时,它似乎正在拾取找到的行。
我通过将循环中的查询修改为以下 运行ning 从工作台和 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** ;
我有以下过程:
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 workbench 调用此过程时,如下所示:
调用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;
}
}
);
}
上面的方法是 运行在一个单独的 transaction.When 中,我在一段时间后终止了事务,我看到它正在等待锁。 在执行 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), undo log entries 307157 MySQL thread id 14, OS thread handle 0x2b38, query id 461758 localhost 127.0.0.1 root Sending data 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;
问题好像是在loop.This更新后的"select row_count() into cnt"语句row_count负责维护循环。 在我的例子中,while 进入无限循环,因为更新所有记录后更新语句始终为真。 当我 运行 mysql 工作台上的查询 separately.I 看到修改了 0 行,6 行 found.While 运行ning 来自 workbench ,row_count 似乎是从修改后的行中填充的,但是当我从 java 程序中 运行 它时,它似乎正在拾取找到的行。 我通过将循环中的查询修改为以下 运行ning 从工作台和 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** ;