Pri*_*asi 64 mysql sql stored-procedures transactions
我的存储过程的基本结构是,
BEGIN
.. Declare statements ..
START TRANSACTION;
.. Query 1 ..
.. Query 2 ..
.. Query 3 ..
COMMIT;
END
Run Code Online (Sandbox Code Playgroud)
MySQL版本: 5.1.61-0ubuntu0.11.10.1-log
目前,如果'query 2'失败,则提交'query 1'的结果.
rko*_*egi 59
看看http://dev.mysql.com/doc/refman/5.0/en/declare-handler.html
基本上你声明了一个将调用rollback的错误处理程序
START TRANSACTION;
DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
ROLLBACK;
EXIT PROCEDURE;
END;
COMMIT;
Run Code Online (Sandbox Code Playgroud)
Pri*_*asi 32
只是rkosegi代码的替代品,
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
Run Code Online (Sandbox Code Playgroud)
小智 9
下面是一个事务示例,它将在错误时回滚并返回错误代码。
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 ;
Run Code Online (Sandbox Code Playgroud)
这是假设自动提交设置为 0。希望这会有所帮助。
[这只是其他答案中未涉及的解释]
至少在最新版本的 MySQL 中,您的第一个查询未提交。
如果您在同一会话下查询它,您将看到更改,但如果您从不同的会话查询它,则更改不存在,它们未提交。
当您打开一个事务并且其中的查询失败时,该事务保持打开状态,它不会提交或回滚更改。
所以要小心,任何表/一行被锁定,就像以前的查询SELECT ... FOR SHARE/UPDATE,UPDATE,INSERT或任何其他锁定查询,一直锁定,直到该会话被杀死(并执行回滚),或直到随后的查询提交它明确(COMMIT)或隐式,从而使部分更改永久化(这可能会在数小时后发生,而交易处于等待状态)。
这就是解决方案涉及ROLLBACK在发生错误时立即声明处理程序的原因。
在处理程序中,您还可以使用 重新引发错误RESIGNAL,否则存储过程将执行“成功”:
BEGIN
DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
ROLLBACK;
RESIGNAL;
END;
START TRANSACTION;
#.. Query 1 ..
#.. Query 2 ..
#.. Query 3 ..
COMMIT;
END
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
84793 次 |
| 最近记录: |