我的mysql是5.1版本,表是innoDB
procedure1:
set autocommit = 0;
start transaction;
****
commit;procedure2:
update a set a.b = 1 where id =1;
问题1:
mysql默认autocommit =1
如果执行了procedure1后,会不会对下次执行procedure2有影响??
就是说执行了procedure1后,procedure2执行时autocommit是不是还是1???
问题2:
mysql是不是对如下存储过程自动执行事务?
procedure3:
update a set a.id = 1 where id =2;
update b set b.id = 1 where id =2;
 

解决方案 »

  1.   

    1、应该只是在SP1中有用,除非在连接后直接设置set autocommit=0;
    2、如果没有设置set autocommit=1,应该是直接执行SQL语句,存入表中。
      

  2.   

    问题1:
    如果执行了procedure1后,会不会对下次执行procedure2有影响??
    会影响就是说执行了procedure1后,procedure2执行时autocommit是不是还是1???
    是0在同一个connection中是同一个autocommit变量。任何时候的修改都会影响后面的。
      

  3.   

    问题2:
    mysql是不是对如下存储过程自动执行事务?不是,要看你的autocommit设置,如果是ON, 则每句SQL后都会自动提交。如果是OFF,则要等到commit;或者DDL等之关的语句来隐式提交。
      

  4.   

    2、如果没有设置set autocommit=0,应该是直接执行SQL语句,存入表中
    将立刻将更新存储到磁盘上。
      

  5.   

    1、在SP1中设置后,autocommit变更为你的设置值,但重新启动后恢复为
    MYSQL默认值
      

  6.   

    重启当然会恢复my.ini文件中的值或者你启动命令参数中的值了。但对这个问题
    如果执行了procedure1后,会不会对下次执行procedure2有影响?? 同一connection 中你做个实现就很容易知道了。
      

  7.   

    做了个小试验
    在ems sql manager 2007 for mysql
    pro1:
    name :test1 
    para: _name varchar(10) _id intset autocommit = 0;
    start transaction;
    update product set name = _name where id = _id;
    update product set code =_name where id=_id;
    commit;pro2:
    name :test2 
    para: _name varchar(10) _id intupdate product set name = _name where id = _id;
    update product set code =_name where id=_id;先调用test1
    call test1('test1',3)
    执行成功
    id 为3 的产品 name 和 code 改为test1再试用 test2
    call test2('test2',3)id 为3 的产品name 和 code 也被改为了test2
    按照上面的说法,调用 test2时应该改不了啊?
    还是我测试有问题??
      

  8.   

    在SP2中没有显式 start transaction
      

  9.   

    又试了一次
    1.call `test1`('test1',3)  ;
    2.rollback;3.call `test2`('test2',3) ;
    4.rollback;
                       
    执行      name code
    1        test1 test1
    3        test2 test2
    一起执行  name code
    1,2      test1 test1
    3, 4     test1 test1//没有变成test2 test2
    1,2,3,4   test1 test1
      

  10.   

    我现在做这个试验的目的是
    我有的procedure 有
    set autocommit =0;
    start transaction; 
    commit;有的procedure 没有
    可能直接就是
    create prcedure p
    begin
    update table set a =1 where id = 2;
    end 
    没有进行事务处理没有进行事务处理的还很多
    我在试验要不要把每个像这种一条语句的存储过程加上事务处理
    像下面这样
    create prcedure p
    begin
    start transaction; 
    update table set a =1 where id = 2;
    commit;
    end 
      

  11.   

    最好显式
    start transaction;
    .....
    commit; 
      

  12.   

    现在我没有加start transaction;
    只有commit;
    应该没有问题吧
      

  13.   

    一个简单的试验,你可以看到在 p1中设置的autocommit=0,运行完p1,p2后然后rollback会把p1,p2把插入的记录全部回滚掉。mysql> create table tab1 (
        ->  id int primary key
        -> ) ENGINE=InnoDB ;
    Query OK, 0 rows affected (0.09 sec)mysql> insert into tab1 values (1);
    Query OK, 1 row affected (0.08 sec)mysql> select * from tab1;
    +----+
    | id |
    +----+
    |  1 |
    +----+
    1 row in set (0.00 sec)mysql>
    mysql> CREATE PROCEDURE p1 ()
        -> BEGIN
        ->  set @@autocommit =0;
        ->  insert into tab1 values (11);
        -> end
        -> //
    Query OK, 0 rows affected (0.00 sec)mysql> CREATE PROCEDURE p2 ()
        -> begin
        ->  insert into tab1 values (12);
        -> end
        -> //
    Query OK, 0 rows affected (0.00 sec)mysql> delimiter ;
    mysql>
    mysql> select @@autocommit;
    +--------------+
    | @@autocommit |
    +--------------+
    |            1 |
    +--------------+
    1 row in set (0.00 sec)mysql> call p1();
    Query OK, 1 row affected (0.00 sec)mysql> select @@autocommit;
    +--------------+
    | @@autocommit |
    +--------------+
    |            0 |
    +--------------+
    1 row in set (0.00 sec)mysql> call p2();
    Query OK, 1 row affected (0.00 sec)mysql> select * from tab1;
    +----+
    | id |
    +----+
    |  1 |
    | 11 |
    | 12 |
    +----+
    3 rows in set (0.00 sec)mysql> rollback;
    Query OK, 0 rows affected (0.05 sec)mysql> select * from tab1;
    +----+
    | id |
    +----+
    |  1 |
    +----+
    1 row in set (0.00 sec)mysql>
      

  14.   

    谢谢,
    对于set autocommit = 0;
    如果执行成功需要 commit;
    如果不成功,要不要显示 执行rollback?如果需要的话,根据什么来判断多个update 或 delete 都执行成功了呢?
    感觉mysql手册讲得不详细
      

  15.   

    执行的结果可以在你的程序中进行判断,如C++你可以直接通过try catch 来捕获错误。在catch 中进行 rollbck
      

  16.   

    我是想在存储过程里直接判断是否成功,成功commit;失败rollback;不知道有没有什么系统变量或其他的来进行判断
      

  17.   

    你可以用 ROW_COUNT()  来确认多少条记录被更新,删除,插入。
      

  18.   

    ROW_COUNT() 函数
    或者 
    error_count 变量
      

  19.   

    1、只有InnoDB支持事务;
    2、我是想在存储过程里直接判断是否成功执行成功是指SQL语句吧?即SQL语句没有问题还是执行SQL语句的结果?前者:可以用捕获错误方法得到,
    · Handler type (CONTINUE, EXIT)//处理类型,继续或退出
    · Handler condition (SQLSTATE, MySQL error code, named condition) //触发条件
    · Hander actions(错误触发的操作) 
    后者:ROW_COUNT() 
      

  20.   

    比如
    procedure begin
    update ...
    update ...
    delete ...
    if 三个语句都没有问题,成功执行,
    commit;
    else
    //其中一个有问题
    rollback;
    end
    我用error_count时有问题,假如你一个有问题,后面二个没问题,error_count还是0而不是1
      

  21.   

    error_count要分别取值,
    update ...
    set @i=error_count
    update ...
    set @i1=error_count
    delete ..
    set @i2=error_count
    分别判断
      

  22.   

    标准的做法手册上有.
    没有必要分开取值判断,并且也没有任何意义,。因为@@error_count是session级的。不会被自动清零。
    所以你只需在最后procedure begin
    update ...
    update ...
    delete ...if 三个语句都没有问题,成功执行,
    if @@error_count>0 then
    commit;
    else
    //其中一个有问题
    rollback;
    end
      

  23.   

    procedure begin 
    update ... 
    update ... 
    delete ... if 三个语句都没有问题,成功执行, 
    if @@error_count>0 then 
    commit; 
    else 
    //其中一个有问题 
    rollback; 
    end 现在就是按照这种方法做的,不知道什么地方出了问题,还要继续检查
    如果第一个update成功,后面的不成功
    不能对其进行回滚
    但是在call procedure之后,执行rollback;这时候可以回滚
      

  24.   

    三条语句中,每条执行完后,执行
    SELECT @@error_count INTO v_ErrorCount;
    IF ( v_ErrorCount <> 0 )
    ROLLBACK TRANSACTION;
    ELSE
    COMMIT TRANSACTION;
    END IF;
    END IF; 
      

  25.   

    上面的写错了if @@error_count=0 then commit;
      

  26.   

    update ...
    SELECT @@error_count INTO v_ErrorCount; 
    SELECT v_ErrorCount;
    update ...
    SELECT @@error_count INTO v_ErrorCount; 
    SELECT v_ErrorCount;
    delete ...
    SELECT @@error_count INTO v_ErrorCount; 
    SELECT v_ErrorCount;
    结果如何
      

  27.   

    发表于:2009-05-06 14:46:0628楼 得分:0 
    三条语句中,每条执行完后,执行 
    SELECT @@error_count INTO v_ErrorCount; 
    IF ( v_ErrorCount <> 0 ) 
    ROLLBACK TRANSACTION; 
    ELSE 
    COMMIT TRANSACTION; 
    END IF; 
    END IF;  不可以这样做,这样就失去原子性了
    我需要它们要生一起生,要死一起死
      

  28.   

    if @@error_count>0 then 改成if @@error_count=0 then 如果error_count>0 则说明有错误发生。
      

  29.   


    你把ROLLBACK TRANSACTION、COMMIT TRANSACTION去掉,目的是检查
    v_ErrorCount中的值是多少。
      

  30.   

    测试了一下,在MYSQL中,
    执行完SQL语句后,select @@error_count看看结果,这个值
    是要随语句执行是否正确而改变的。
    比如:
    select * from t5;
    T5不存在,则@@error_count=1
    再执行
    select * from t4;
    T4存在,则@@error_count=0
      

  31.   

    需要用到异常处理,对msyql不太熟,问题解决了再回来
      

  32.   

    在23楼就问过,是SQL语句有问题还是执行结果有问题?
      

  33.   


    你的错误是指什么语句错误还是没有值被更新? 列举一个可能的错误。
    估计你是想用ROW_COUNT()