mysql 实现事务的提交与回滚

最近要对数据库的数据进行一个定时迁移,为了防止在执行过程sql语句因为某些原因报错而导致数据转移混乱,因此要对我们的脚本加以事务进行控制。

首先我们建一张tran_test表

CREATE TABLE tran_test(
f1 VARCHAR(10) NOT NULL,
f2 INT(1) DEFAULT NULL,
PRIMARY KEY (f1)
)ENGINE=INNODB CHARSET=utf8

我想对tran_test插入两条数据,但是为了防止插入中报错,因此我要把插入语句控制在一个事务内。

这时候,如果你查一下有些人的文章,许多时候会给出你这么一条答案。

START TRANSACTION;
INSERT INTO tran_test VALUES(‘A‘,1);
INSERT INTO tran_test VALUES(‘B‘,2);
ROLLBACK;

START TRANSACTION;
INSERT INTO tran_test VALUES(‘A‘,1);
INSERT INTO tran_test VALUES(‘B‘,2);
COMMIT;

看上去很简单的sql语句,并且这两句也确实能实现提交或回滚。

然而这真的能达到我们的目的吗?答案是否定的。

比如第一段,它是将你在事务中的sql语句无论对错全部进行ROLLBACK。这样绝对的回滚使得你的sql没有任何意义了。

因此我们想要真正的控制好事务,我的思路是对要执行的sql进行异常检测。如果sql没有出现异常,COMMIT,如果捕获到了异常,则ROLLBACK。

这时候,我们就需要建一个存储过程来捕获异常。执行成功时进行COMMIT,sql执行失败时则进行ROLLBACK。

两种思路可以达到我想要的效果。

第一种是对我们要执行的sql进行异常捕获,我们再定义一个变量t_error,当捕获到异常的时候,让t_error=1。再对t_error进行条件判断,如果t_error=1则进行ROLLBACK,否则进行COMMIT。

DROP PROCEDURE IF EXISTS t_test;
DELIMITER //
CREATE PROCEDURE t_test()
  BEGIN
    DECLARE t_error INTEGER;
    DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SET t_error = 1;
    START TRANSACTION;
         INSERT INTO tran_test VALUES(‘A‘,1);
     INSERT INTO tran_test VALUES(‘B‘,2);
         IF t_error = 1 THEN
             ROLLBACK;
         ELSE
             COMMIT;
         END IF;
END//
CALL t_test();

另一只则是第一种的简化,即捕获到异常直接进行ROLLBACK,如果没捕获到异常,直接COMMIT

DROP PROCEDURE  IF EXISTS t_test;
DELIMITER //
CREATE PROCEDURE t_test()
BEGIN
DECLARE EXIT HANDLER FOR SQLEXCEPTION ROLLBACK;
START TRANSACTION;
INSERT INTO tran_test VALUES(‘A‘,1);
INSERT INTO tran_test VALUES(‘B‘,2);
COMMIT;
END//
CALL t_test()

这样,这两个insert语句便真正的被控制在了一个事务内了。

原文地址:https://www.cnblogs.com/lykbk/p/sdfdfdf23423434345.html

时间: 2024-10-12 07:46:42

mysql 实现事务的提交与回滚的相关文章

mysql事务的提交和回滚

START TRANSACTION | BEGIN [WORK] COMMIT [WORK] [AND [NO] CHAIN] [[NO] RELEASE] ROLLBACK [WORK] [AND [NO] CHAIN] [[NO] RELEASE] SET AUTOCOMMIT = {0 | 1} 以上是mysql创建存储过程的官方语法.    我这里要说明的mysql事务处理多个SQL语句的回滚情况.比如说在一个存储过程中启动一个事务,这个事务同时往三个表中插入数据,每插完一张表需要判断其

RocketMQ源码分析之RocketMQ事务消息实现原下篇(事务提交或回滚)

本文将重点分析RocketMQ Broker如何处理事务消息提交.回滚命令,根据前面的介绍,其入口EndTransactionProcessor#proce***equest: OperationResult result = new OperationResult();if (MessageSysFlag.TRANSACTION_COMMIT_TYPE == requestHeader.getCommitOrRollback()) { // @1result = this.brokerCont

对mysql事务提交、回滚的错误理解

一.起因 begin或者START TRANSACTION开始一个事务 rollback事务回滚 commit 事务确认 人们对事务的解释如下:事务由作为一个单独单元的一个或多个SQL语句组成,如果其中一个语句不能完成,整个单元就会回滚(撤销),所有影响到的数据将返回到事务开始以前的状态.因而,只有事务中的所有语句都成功地执行才能说这个事务被成功地执行.  这句话本身没有什么问题,问题是我给理解错了,我测试中问题描述为如下: mysql事务中有两条insert语句,其中第二条语句是错误的,在运行

【转】批量复制操作(SqlBulkCopy)的出错处理:事务提交、回滚

原文地址:http://blog.csdn.net/westsource/article/details/6658109 默认情况下,批量复制操作作为独立的操作执行. 批量复制操作以非事务性方式发生,不可能使其回滚. 如果需要在出错时回滚全部批量复制或它的一部分,可以使用 SqlBulkCopy 托管的事务,在现有事务中执行批量复制操作,或者在 System.Transactions Transaction 中登记它. 由于不同批次在不同事务中执行,因此,如果在批量复制操作期间发生错误,则当前批

切分大任务成多个子任务(事务),汇总后统一提交或回滚

示例代码可以从github上获取 https://github.com/git-simm/simm-framework.git 一.业务场景: 系统中存在一个盘库的功能,用户一次盘库形成一两万条的盘库明细单,一次性提交给服务器进行处理.服务器性能比较优越,平均也得运行30秒左右.性能上需要进行优化. 二.处理方案: 做过代码分析后,发现单线程逻辑没有什么优化空间.开始考虑引入多线程处理模型,用10个子线程进行任务切分处理.切分子线程问题需要考虑事务的一致性.10个子线程对应10个事务,需要保证所

MySQL【Update误操作】回滚(转)

前言:      继上一篇MySQL[Delete误操作]回滚之后,现在介绍下Update回滚,操作数据库时候难免会因为“大意”而误操作,需要快速恢复的话通过备份来恢复是不太可能的,因为需要还原和binlog差来恢复,等不了,很费时.这里说明因为Update 操作的恢复方法:主要还是通过binlog来进行恢复,前提是binlog_format必须是Row格式,否则只能通过备份来恢复数据了.和上一篇的条件一样.方法:     条件:开启Binlog,Format为Row.     步骤:1.通过M

c++ mysql事务提交及回滚

之前在做有关数据库的操作时发现,有些内容应该作为一个事务一起提交,而不是每个都单独提交,这就需要把这些操作当做一个事务来处理.而我之前写过简单的数据库的操作,因为mysql默认的是自动提交,我们就需要用到api--mysql_commit(). mysql_commit(MYSQL* mysql, my_bool mode); mode为1时表示ON,mode为0时表示OFF. 在关掉自动提交后,以后我们的操作就需要自己手动提交了,而这就是我们所需要的了,对于一系列的操作,如果都成功了,那我们就

(MYSQL学习笔记4)事务的开启、提交、回滚

使用事务要注意以下三点: 1.在 MySQL 中只有使用了 Innodb 数据库引擎的数据库或表才支持事务. 2.事务处理可以用来维护数据库的完整性,保证成批的 SQL 语句要么全部执行,要么全部不执行. 3.事务用来管理 insert,update,delete 语句 MYSQL 事务处理主要有两种方法: 1.用 BEGIN, ROLLBACK, COMMIT来实现 BEGIN 开始一个事务 ROLLBACK 事务回滚 COMMIT 事务确认 2.直接用 SET 来改变 MySQL 的自动提交

c语言mysql数据库事务开始、提交、回滚范例

1. 事务提交模式修改:修改数据库提交模式为0[手动提交] memset ( sql, 0x00, sizeof( sql ) ); memcpy ( sql, "set autocommit=0;", 17 ); if( mysql_query( sock, sql ) ){ sprintf( g_acTrcMsg, "关闭自动提交模式失败[%d][%s]", mysql_errno( sock ), mysql_error( sock ) );TRCLOG1 r