MySQL存儲過程 事務transaction


MySQL 中,單個 Store Procedure(SP) 不是原子操作,而 Oracle 則是原子的。如下的存儲過程,即使語句2 失敗,語句 1 仍然會被 commit 到數據庫中:

create table testproc(id int(4) primary key, name varchar(100));  
   
CREATE PROCEDURE test_proc_ins(  
IN i_id INT,  
IN i_name VARCHAR(100)  
)  
BEGIN  
           INSERT INTO testproc VALUES (i_id, i_name);  -- 語句1  
           INSERT INTO testproc VALUES (i_id, i_name);  -- 語句2(因為id為PK,此語句將出錯)。  
END;  

要使整個存儲過程成為一個原子操作的辦法是:在存儲過程主體開始部分,指定開始一個事務。語句 2 失敗,語句 1 不會被 commit 到數據庫中,存儲過程將會在調用時拋出一個異常。

CREATE PROCEDURE test_proc_ins(  
IN i_id INT,  
IN i_name VARCHAR(100)  
)  
BEGIN  
start transaction; --整個存儲過程指定為一個事務  
           INSERT INTO testproc VALUES (i_id, i_name);  
           INSERT INTO testproc VALUES (i_id+1, i_name); -- 這里把id+1,避免主鍵沖突  
commit; -- 語句1。必須主動提交  
END;  

 

 

 

CREATE PROCEDURE test_proc_ins(  
IN i_id INT,  
IN i_name VARCHAR(100),  
OUT o_ret INT)  
BEGIN  
start transaction;  
           INSERT INTO testproc VALUES (i_id, i_name);  
           INSERT INTO testproc VALUES (i_id+1,i_name);  
           commit; -- 語句1,提交后,事務已結束  
           set o_ret = 1;  
           start transaction; -- 再啟一個事務  
           INSERT INTO testproc VALUES (i_id+2,i_name); -- 語句2  
           INSERT INTO testproc VALUES (i_id+2,i_name); -- 語句3  
           set o_ret = 2;  
           commit; -- 數據正常的情況下,需要再次commit以結束事務  
END;  

MySQL的回滾事物的操作

在處理事務時,使用SQLException捕獲SQL錯誤,然后處理; 按照這個推論,我們必須在MySQL存儲過程中捕獲SQL錯誤,最后判斷是回滾(ROLLBACK)還是提交(COMMIT)。

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;    
   select t_error;   //返回標識位的結果集;  
END  

mysql事物處理實例

MYSQL的事務處理主要有兩種方法
1.用begin,rollback,commit來實現
    begin開始一個事務
    rollback事務回滾
    commit 事務確認
2.直接用set來改變mysql的自動提交模式
    mysql默認是自動提交的,也就是你提交一個query,就直接執行!可以通過
    set autocommit = 0 禁止自動提交
    set autocommit = 1 開啟自動提交
    來實現事務的處理。
但要注意當用set autocommit = 0 的時候,你以后所有的sql都將作為事務處理,直到你用commit確認或 rollback結束,注意當你結束這個事務的同時也開啟了新的事務!按第一種方法只將當前的做為一個事務!
MYSQL只有 INNODB和BDB類型的數據表才支持事務處理,其他的類型是不支持的!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM