MySQL:存储过程中的事务
我的存储过程的基本结构是,
BEGIN .. Declare statements .. START TRANSACTION; .. Query 1 .. .. Query 2 .. .. Query 3 .. COMMIT; END
MySQL版本: 5.1.61-0ubuntu0.11.10.1-log
目前,如果“查询2”失败,则提交“查询1”的结果。
- 如果任何一个查询失败,我怎样才能回滚事务?
看看http://dev.mysql.com/doc/refman/5.0/en/declare-handler.html
基本上你声明error handling程序将调用回滚
START TRANSACTION; DECLARE EXIT HANDLER FOR SQLEXCEPTION BEGIN ROLLBACK; EXIT PROCEDURE; END; COMMIT;
只是rkosegi的代码的一个替代scheme,
BEGIN .. Declare statements .. DECLARE EXIT HANDLER FOR SQLEXCEPTION BEGIN .. set any flags etc eg. SET @flag = 0; .. ROLLBACK; END; START TRANSACTION; .. Query 1 .. .. Query 2 .. .. Query 3 .. COMMIT; .. eg. SET @flag = 1; .. END
MySQL存储过程中的事务
要在MySQL存储过程中执行ROLLBACK,我们必须在存储过程中声明退出处理程序。 在MySQL存储过程中有两种types的处理程序。
- 的SQLException
- 一个SQLWarning
当查询执行期间发生任何错误时, sqlexception将执行 ,并且当MySQL存储过程发生任何警告时, 将执行sqlwarning 。 我们来看看如何在“存储过程”中使用这些块。
DELIMITER $$ CREATE PROCEDURE `transaction_sp` () BEGIN DECLARE exit handler for sqlexception BEGIN -- ERROR ROLLBACK; END; DECLARE exit handler for sqlwarning BEGIN -- WARNING ROLLBACK; END; START TRANSACTION; INSERT INTO table_name (id, name, address) values ('1','Avinash','xpertdeveloper.com'); UPDATE second_table set name="xyz" where id=4; COMMIT; END $$
下面是一个事务回滚的例子,并返回错误代码。
DELIMITER $$ CREATE DEFINER=`root`@`localhost` PROCEDURE `SP_CREATE_SERVER_USER`( IN P_server_id VARCHAR(100), IN P_db_user_pw_creds VARCHAR(32), IN p_premium_status_name VARCHAR(100), IN P_premium_status_limit INT, IN P_user_tag VARCHAR(255), IN P_first_name VARCHAR(50), IN P_last_name VARCHAR(50) ) BEGIN DECLARE errno INT; DECLARE EXIT HANDLER FOR SQLEXCEPTION BEGIN GET CURRENT DIAGNOSTICS CONDITION 1 errno = MYSQL_ERRNO; SELECT errno AS MYSQL_ERROR; ROLLBACK; END; START TRANSACTION; INSERT INTO server_users(server_id, db_user_pw_creds, premium_status_name, premium_status_limit) VALUES(P_server_id, P_db_user_pw_creds, P_premium_status_name, P_premium_status_limit); INSERT INTO client_users(user_id, server_id, user_tag, first_name, last_name, lat, lng) VALUES(P_server_id, P_server_id, P_user_tag, P_first_name, P_last_name, 0, 0); COMMIT WORK; END$$ DELIMITER ;
这是假设autocommit设置为0.希望这有助于。
有些时候我上面写的程序是行不通的。 所以我改变结构如下。
begin declare exit handler for SQLEXCEPTION begin ROLLBACK; select 'An unpexpected error sprunged in your transaction.try again!' as 'Error'; end; start transaction; insert into transact values(1,t_type,amount,tTime,accNo); insert into rate values(name,age,years); insert into tax values(ols,timed,sss); commit; end;
'声明SQLEXCEPTION退出处理程序'语句,我写在一个开始,结束块。第一次我用它没有开始,结束块。 但是这对我的程序是一个错误。