锁表为何失败CREATE PROCEDURE `ba`(id int)
beginlock table ba2 read;
update ba2 a, (select max(a) as aa from ba2 where a < id) b set a.b=1 where a.a=b.aa;
delete from ba2 where a=id;
unlock tables;
end; 我用工具窗口执行下面的代码
lock table ba2 read;
update ba2 a, (select max(a) as aa from ba2 where a < id) b set a.b=1 where a.a=b.aa;
delete from ba2 where a=id;
unlock tables;失败提示:1100--table ba2 was not locked with LOCK tAbles;why 锁表为何失败
beginlock table ba2 read;
update ba2 a, (select max(a) as aa from ba2 where a < id) b set a.b=1 where a.a=b.aa;
delete from ba2 where a=id;
unlock tables;
end; 我用工具窗口执行下面的代码
lock table ba2 read;
update ba2 a, (select max(a) as aa from ba2 where a < id) b set a.b=1 where a.a=b.aa;
delete from ba2 where a=id;
unlock tables;失败提示:1100--table ba2 was not locked with LOCK tAbles;why 锁表为何失败
解决方案 »
- 求一行联动查询代码!!
- MYSQL服務器掛了!!求分析引起此類錯誤的原因。附錯誤日誌
- 请问这样的sql语句怎么写?
- com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException
- 初学POSTGRESSQL 的问题
- sql 性能比较,请教
- 一台sever上怎么配置mysql主从?着急啊!
- 从4.0升级到4.1,拷贝原来4.0的data目录覆盖掉到4.1的data目录后,还需要做哪些步骤?
- 求指点 关于索引的问题 联合唯一索引 普通索引的问题
- mysql如何查询数据中每周的数据,有很多周,需要把每周的数据分别查询
- 这里事务该如何进行改写下面的 存储过程
- 怎么获得与我给出的日期最接近的值
为什么我的会是失败lock table ba2 read;
你的write会成功(使用别名成功)
CREATE PROCEDURE `ba`(id int)
beginock table ba2 WRITE, ba2 a WRITE;
update ba2 a, (select max(a) as aa from ba2 where a < id) b set a.b=1 where a.a=b.aa;
delete from ba2 where a=id;
unlock tables;
end; 提示错误 ---1314--lock is not allowed in store procedure
你的意思只能用事务来实现 ?????
这里事务该如何作
(或者我在java代码里 用程序来写?????)
START TRANSACTION [WITH CONSISTENT SNAPSHOT] | BEGIN [WORK]
COMMIT [WORK] [AND [NO] CHAIN] [[NO] RELEASE]
ROLLBACK [WORK] [AND [NO] CHAIN] [[NO] RELEASE]
SET autocommit = {0 | 1}The START TRANSACTION or BEGIN statement begins a new transaction. COMMIT commits the current transaction, making its changes permanent. ROLLBACK rolls back the current transaction, canceling its changes. The SET autocommit statement disables or enables the default autocommit mode for the current session.
MySQL LOCK 类型MySQL LOCK 锁的类型有四种,每一种锁定的范围不同:
READ所有的用户只能读取被锁表,不能对表进行修改(包括执行 LOCK 的用户),当表不存在 WRITE 写锁时 READ 读锁被执行。
READ LOCAL除了允许 INSERT 命令以外执行的锁与 READ 相同。
WRITE除了当前用户被允许读取和修改被锁表外,其他用户的所有访问被完全阻止。一个 WRITE 写锁被执行仅当所有其他锁取消时。
LOW PRIORITY WRITE低优先级的读锁,在等待时间内(等待其他锁取消),其他用户的访问将被认为是执行了 READ 读锁,因此将增加等待时间。 java 程序时下如下:
conn = connection();
conn.setAutocommit(false);
lockStatement=conn.createStatement();
lockStatement.execute("Lock tables mm write");
ps=conn.prepareStatement("select * from message where"");
rs=ps.executeQuery();
where....rs.next();...
messDBO.insert....()catch(sqlexception e)
{
commit=false;
throw e;
}
finally{
if(commit)
conn.commit();
else
conn.rollback();stagement unlockStagement=conn.createStagement();
unlockStagement.execute("unlock Tables");
if(ps!=null) ps.close();
if(lockStagement!=null) unlockStagement.close();
if(unlockStagement!=null) unlockStagement.cluse();
freeconnection()}
现在就缺楼上补充
事务来实现 ?????
这里事务该如何作
其他是不能读的3. 当线程发出另外一个LOCK TABLES时,或当服务器的连接被关闭时,
当前线程锁定的所有表会自动被解锁。---------------这个是很重要的
4. 当前进程无法 访问没有被LOCK 的表 这个不清楚的可以在winows 下开两个命令窗口 (就相当是两个进程了) 然后试
delimiter |
----------------------------------
-- rep_shadow_rs
-- 用来处理信息的增加,更新和删除
-- 每次只更新上次以来没有做过的数据
-- 根据不同的标志位
-- 需要一个输出的参数,
-- 如果返回为0,则调用失败,事务回滚
-- 如果返回为1,调用成功,事务提交
--
-- 测试方法
-- call pro_rep_shadow_rs(@rtn);
-- select @rtn;
----------------------------------
create procedure pro_rep_shadow_rs(out rtn int)
begin
-- 声明变量,所有的声明必须在非声明的语句前面
declare iLast_rep_sync_id int default -1;
declare iMax_rep_sync_id int default -1;
-- 如果出现异常,或自动处理并rollback,但不再通知调用方了
-- 如果希望应用获得异常,需要将下面这一句,以及启动事务和提交事务的语句全部去掉
declare exit handler for sqlexception rollback;
-- 查找上一次的
select eid into iLast_rep_sync_id from rep_de_proc_log where tbl='rep_shadow_rs';
-- 如果不存在,则增加一行
if iLast_rep_sync_id=-1 then
insert into rep_de_proc_log(rid,eid,tbl) values(0,0,'rep_shadow_rs');
set iLast_rep_sync_id = 0;
end if;
-- 下一个数字
set iLast_rep_sync_id=iLast_rep_sync_id+1;
-- 设置默认的返回值为0:失败
set rtn=0;
-- 启动事务
start transaction;
-- 查找最大编号
select max(rep_sync_id) into iMax_rep_sync_id from rep_shadow_rs;
-- 有新数据
if iMax_rep_sync_id>=iLast_rep_sync_id then
-- 调用
call pro_rep_shadow_rs_do(iLast_rep_sync_id,iMax_rep_sync_id);
-- 更新日志
update rep_de_proc_log set rid=iLast_rep_sync_id,eid=iMax_rep_sync_id where tbl='rep_shadow_rs';
end if;
-- 运行没有异常,提交事务
commit;
-- 设置返回值为1
set rtn=1;
end;
|
delimiter ;
drop procedure if exists pro_rep_shadow_rs_do;
delimiter |
---------------------------------
-- 处理指定编号范围内的数据
-- 需要输入2个参数
-- last_rep_sync_id 是编号的最小值
-- max_rep_sync_id 是编号的最大值
-- 无返回值
---------------------------------
create procedure pro_rep_shadow_rs_do(last_rep_sync_id int, max_rep_sync_id int)
begin
declare iRep_operationtype varchar(1);
declare iRep_status varchar(1);
declare iRep_Sync_id int;
declare iId int;
-- 这个用于处理游标到达最后一行的情况
declare stop int default 0;
-- 声明游标
declare cur cursor for select id,Rep_operationtype,iRep_status,rep_sync_id from rep_shadow_rs where rep_sync_id between last_rep_sync_id and max_rep_sync_id;
-- 声明游标的异常处理,设置一个终止标记
declare CONTINUE HANDLER FOR SQLSTATE '02000' SET stop=1;
-- 打开游标
open cur;
-- 读取一行数据到变量
fetch cur into iId,iRep_operationtype,iRep_status,iRep_Sync_id;
-- 这个就是判断是否游标已经到达了最后
while stop <> 1 do
-- 各种判断
if iRep_operationtype='I' then
insert into rs0811 (id,fnbm) select id,fnbm from rep_shadow_rs where rep_sync_id=iRep_sync_id;
elseif iRep_operationtype='U' then
begin
if iRep_status='A' then
insert into rs0811 (id,fnbm) select id,fnbm from rep_shadow_rs where rep_sync_id=iRep_sync_id;
elseif iRep_status='B' then
delete from rs0811 where id=iId;
end if;
end;
elseif iRep_operationtype='D' then
delete from rs0811 where id=iId;
end if;
-- 读取下一行的数据
fetch cur into iId,iRep_operationtype,iRep_status,iRep_Sync_id;
end while; -- 循环结束
close cur; -- 关闭游标
end;
|