MYSQL 事务异常捕获

newsdy_ 2014-12-02 01:41:54
我想写一个mysql事务,如果query执行异常则回滚,否则提交,但是搜了半天都是在存储过程中实现的,怎么不写存储过程实现这个功能呢,存储过程的代码大致都是这样的:
DELIMITER $$
DROP PROCEDURE IF EXISTS test_sp1 $$
CREATE PROCEDURE test_sp1( )
BEGIN
DECLARE t_error INTEGER DEFAULT 0;
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SET t_error=1;

START TRANSACTION;
INSERT INTO test VALUES(NULL, 'test sql 001');
INSERT INTO test VALUES('1', 'test sql 002');

IF t_error = 1 THEN
ROLLBACK;
ELSE
COMMIT;
END IF;

END$$
DELIMITER ;
怎么写直接开启一个事务,然后判断异常。如果事务非得在存储过程中写,那也太不灵活了吧,刚看mysql,不懂,望大神指导
...全文
429 10 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
benluobo 2014-12-02
  • 打赏
  • 举报
回复
很简单 楼主说的是匿名块 mssql和plsql都支持 mysql是没有这种的,mysql必须通过命名块,也就是存储过程来执行
wwwwb 2014-12-02
  • 打赏
  • 举报
回复
MYSQL不支持匿名块,不用想了
newsdy_ 2014-12-02
  • 打赏
  • 举报
回复
唉,都不是想要的,这if 当条件判断语句如果不在存储过程中就报错啊,怎么这么奇葩,我脑袋大了
知道就是你 2014-12-02
  • 打赏
  • 举报
回复
引用 5 楼 newsdy_ 的回复:
[quote=引用 3 楼 trainee 的回复:] 不在存储过程写也可以啊, 把你的流程写在你的应用程序中。 不要用declare 就可以了 由你的应用程序来判断每条语句的执行结果, 错误就发语句rollback
不用程序控制,直接在sql语句中判断,就像mssql类似,有没有这种可能呢[/quote]
set @a=1;
select @a:=count(0) from table1;
if @a>0
...
else
...
end if; 
知道就是你 2014-12-02
  • 打赏
  • 举报
回复
在程序中捕获异常或 直接执行查询SQL语句,对得到的结果判定即可
newsdy_ 2014-12-02
  • 打赏
  • 举报
回复
引用 3 楼 trainee 的回复:
不在存储过程写也可以啊, 把你的流程写在你的应用程序中。 不要用declare 就可以了 由你的应用程序来判断每条语句的执行结果, 错误就发语句rollback
不用程序控制,直接在sql语句中判断,就像mssql类似,有没有这种可能呢
newsdy_ 2014-12-02
  • 打赏
  • 举报
回复
引用 1 楼 JenMinZhang 的回复:
如果感觉异常在存储过程中比较麻烦,可以定义成有返回值的存储过程,在程序中判断即可,例如:
CREATE  
PROCEDURE  ps_ddgl_ggwxx_insert(IN ps_sblxid INT(11), IN ps_sblxmc VARCHAR(20)  CHARACTER SET UTF8, IN ps_ggwzbh VARCHAR(20) CHARACTER SET UTF8, IN ps_ggwzmc VARCHAR(20) CHARACTER SET UTF8, IN ps_bzxx VARCHAR(20) CHARACTER SET UTF8, OUT exceResult INT)
  COMMENT '新增广告位'
BEGIN
  START TRANSACTION;
  select  count(*) into @likeset   from   ddgl_ggwxx  where   ggwzbh = ps_ggwzbh  ;
  select  count(*) into @totals   from   ddgl_ggwxx  where   sblxid = ps_sblxid  ;
  select   ggwsx into @ggwsx   from   ddgl_sblx  where  lx_id  = ps_sblxid  ;
   IF(@totals >= @ggwsx) then
    SET exceResult = 3;
  ELSEIF(@likeset >0) then
   SET exceResult = 2;
 else
INSERT INTO ddgl_ggwxx ( sblxid, sblxmc, ggwzbh, ggwzmc, bzxx) VALUES(ps_sblxid, ps_sblxmc, ps_ggwzbh, ps_ggwzmc, ps_bzxx);
  COMMIT;
  SET exceResult = 1;
end if  ;
END
还是非得写存储过程对吗,我现在就想摆脱存储过程,直接执行sql语句,像mssql那样,可直接在sql语句中判断异常,不必写存储过程
trainee 2014-12-02
  • 打赏
  • 举报
回复
不在存储过程写也可以啊, 把你的流程写在你的应用程序中。 不要用declare 就可以了 由你的应用程序来判断每条语句的执行结果, 错误就发语句rollback
newsdy_ 2014-12-02
  • 打赏
  • 举报
回复
引用 楼主 newsdy_ 的回复:
我想写一个mysql事务,如果query执行异常则回滚,否则提交,但是搜了半天都是在存储过程中实现的,怎么不写存储过程实现这个功能呢,存储过程的代码大致都是这样的: DELIMITER $$ DROP PROCEDURE IF EXISTS test_sp1 $$ CREATE PROCEDURE test_sp1( ) BEGIN DECLARE t_error INTEGER DEFAULT 0; DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SET t_error=1; START TRANSACTION; INSERT INTO test VALUES(NULL, 'test sql 001'); INSERT INTO test VALUES('1', 'test sql 002'); IF t_error = 1 THEN ROLLBACK; ELSE COMMIT; END IF; END$$ DELIMITER ; 怎么写直接开启一个事务,然后判断异常。如果事务非得在存储过程中写,那也太不灵活了吧,刚看mysql,不懂,望大神指导
还是非得写存储过程对吗,我现在就想摆脱存储过程,直接执行sql语句,像mssql那样,可直接在sql语句中判断异常,不必写存储过程
知道就是你 2014-12-02
  • 打赏
  • 举报
回复
如果感觉异常在存储过程中比较麻烦,可以定义成有返回值的存储过程,在程序中判断即可,例如:
CREATE  
PROCEDURE  ps_ddgl_ggwxx_insert(IN ps_sblxid INT(11), IN ps_sblxmc VARCHAR(20)  CHARACTER SET UTF8, IN ps_ggwzbh VARCHAR(20) CHARACTER SET UTF8, IN ps_ggwzmc VARCHAR(20) CHARACTER SET UTF8, IN ps_bzxx VARCHAR(20) CHARACTER SET UTF8, OUT exceResult INT)
  COMMENT '新增广告位'
BEGIN
  START TRANSACTION;
  select  count(*) into @likeset   from   ddgl_ggwxx  where   ggwzbh = ps_ggwzbh  ;
  select  count(*) into @totals   from   ddgl_ggwxx  where   sblxid = ps_sblxid  ;
  select   ggwsx into @ggwsx   from   ddgl_sblx  where  lx_id  = ps_sblxid  ;
   IF(@totals >= @ggwsx) then
    SET exceResult = 3;
  ELSEIF(@likeset >0) then
   SET exceResult = 2;
 else
INSERT INTO ddgl_ggwxx ( sblxid, sblxmc, ggwzbh, ggwzmc, bzxx) VALUES(ps_sblxid, ps_sblxmc, ps_ggwzbh, ps_ggwzmc, ps_bzxx);
  COMMIT;
  SET exceResult = 1;
end if  ;
END
关于mysql事务处理 public static void StartTransaction(Connection con, String[] sqls) throws Exception { if (sqls == null) { return; } Statement sm = null; try { // 事务开始 System.out.println("事务处理开始!"); con.setAutoCommit(false); // 设置连接不自动提交,即用该连接进行的操作都不更新到数据库 sm = con.createStatement(); // 创建Statement对象 //依次执行传入的SQL语句 for (int i = 0; i < sqls.length; i++) { sm.execute(sqls[i]);// 执行添加事物的语句 } System.out.println("提交事务处理!"); con.commit(); // 提交给数据库处理 System.out.println("事务处理结束!"); // 事务结束 //捕获执行SQL语句组中的异常 } catch (SQLException e) { try { System.out.println("事务执行失败,进行回滚!\n"); con.rollback(); // 若前面某条语句出现异常时,进行回滚,取消前面执行的所有操作 } catch (SQLException e1) { e1.printStackTrace(); } } finally { sm.close(); } } 通常都是上述的写法, 在mysql 不支持事务的时候 , 中间的 setAutoCommit 的事务操作是不是都不生效. 现在innoDB支持 事务了, 上述的 java 代码是否能实现 以下的 事务隔离的 操作, 在修改的时候处于锁定状态 或者 只可以通过存储过程来实现, 单行的锁定 BEGIN; SELECT book_number FROM book WHERE book_id = 123 FOR UPDATE; --这里for update , 以前用Oracle的时候也是有这个行锁 // ... UPDATE book SET book_number = book_number - 1 WHERE book_id = 123; COMMIT;

57,063

社区成员

发帖
与我相关
我的任务
社区描述
MySQL相关内容讨论专区
社区管理员
  • MySQL
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧