一、起因

  begin或者START TRANSACTION开始一个事务

  rollback事务回滚
  commit 事务确认

 人们对事务的解释如下:事务由作为一个单独单元的一个或多个SQL语句组成,如果其中一个语句不能完成,整个单元就会回滚(撤销),所有影响到的数据将返回到事务开始以前的状态。因而,只有事务中的所有语句都成功地执行才能说这个事务被成功地执行。

  这句话本身没有什么问题,问题是我给理解错了,我测试中问题描述为如下:

 mysql事务中有两条insert语句,其中第二条语句是错误的,在运行完事务后,第一条仍然插进去了,代码如下。

 //创建表:
CREATE TABLE `test_tab` (
`f1` int(11) NOT NULL ,
`f2` varchar(11) DEFAULT NULL ,
PRIMARY KEY (`f1`)
)
ENGINE=InnoDB //执行事务:
START TRANSACTION;
INSERT INTO test_tab VALUES (1, '2');
INSERT INTO test_tab VALUES (1, '3');
COMMIT;

(错误:这只是我一开始的认为)一开始认为只要把事务写出来,最后用commit提交一下,数据库会自动判断这些语句是否全执行成功,如果成功则把所有的数据插入到数据库,如果有一条失败就自动回滚至原始状态!显然我认为错了。

我执行上面的语句后的结果是:

[SQL]START TRANSACTION;

受影响的行: 0

时间: 0.000s

[SQL]

INSERT INTO test_tab VALUES (1, '2');

受影响的行: 1

时间: 0.001s

[SQL]

INSERT INTO test_tab VALUES (1, '3');

[Err] 1062 - Duplicate entry '1' for key 'PRIMARY'

我们看结果可以知道INSERT INTO test_tab VALUES (1, '3');这一句因为主键冲突运行失败,从而这一条下面的commit也没有执行。

需要注意的是:这时已经开启了一个事务,并且已经执行了一条正确的插入语句,虽然没有体现在数据库中,但如果以后在该连接中又执行了一条commit 或begin或start transaction(新开一个事务会将该链接中的其他未提交的事务提交,相当于commit!)你会发现已经将刚才的INSERT INTO test_tab VALUES (1, '2');写进了数据库。

所以事务的回滚不是这么理解的,正确的理解应该是,如果事务中所有sql语句执行正确则需要自己手动提交commit;否则有任何一条执行错误,需要自己提交一条rollback,这时会回滚所有操作,而不是commit会给你自动判断和回滚。

二 解决办法

  1. C++调用方式:(简单示例)

先定义一个变量标志bool m_flag=true;

再执行事务和sql语句如:(execute为自己写的函数,如下)

execute( m_sqlCon, “begin”);

execute(m_sqlCon,”INSERT INTO test_tab VALUES (1, '2')”);

execute(m_sqlCon,”INSERT INTO test_tab VALUES (1, '3')”);

如果执行过程中任意一语句出错则将该标志m_flag置为false。

这时不应该去提交commit,而是用一个函数去判断标志是否为false,如果为false说明执行的sql语句中有失败的,就执行rollback,否则说明全部正确,执行commit。如下面的 commit_transaction()方法。

代码大致如下,如使用需要修改!

 1 privat void execute(MYSQL m_sqlCon, string sqlStatement)
2 {
3 r = mysql_real_query(m_sqlCon, sqlStatement, (unsigned long)strlen(sqlStatement));
4 if (r)
5 m_flag = false; // 出错则标记一下
6 }
7 public bool commit_transaction()
8 {
9 int ret_error = 0;
10 if (!m_flag)
11 {
12 cancel_transaction();
13 return false;
14 }
15 else
16 {
17 if (!(ret_error = mysql_commit(m_sqlCon)))
18 {
19 cancel_transaction();
20 return true;
21 }
22 }
23 return true;
24 }

2.利用存储过程:

 1 CREATE PROCEDURE PRO2()
2 BEGIN
3 DECLARE t_error INTEGER;
4 DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SET t_error = 1;
5
6 START TRANSACTION;
7 INSERT INTO test_tab VALUES (1, '2');
8 INSERT INTO test_tab VALUES (1, '3');
9
10 IF t_error = 1 THEN
11 ROLLBACK;
12 ELSE
13 COMMIT;
14 END IF;
15 END

然后调用 CALL  PRO2()

这个直接可以利用mysql去决定他应该是回滚还是提交。

转自:https://www.cnblogs.com/jaejaking/p/5342285.html

对mysql事务提交、回滚的错误理解的更多相关文章

  1. 第二百八十六节,MySQL数据库-MySQL事务操作(回滚)

    MySQL数据库-MySQL事务操作(回滚) 事务用于将某些操作的多个SQL作为原子性操作,一旦有某一个出现错误,即可回滚到原来的状态,从而保证数据库数据完整性. 举例:有这样一张表 从表里可以看出张 ...

  2. MySql事务无法回滚的原因

    使用MySQL时.假设发现事务无法回滚,但Hibernate.Spring.JDBC等配置又没有明显问题时.不要苦恼,先看看MySQL创建的表有没有问题.即表的类型. InnoDB和MyISAM是在使 ...

  3. JDBC事务提交/回滚实例

    以下是使用事务教程中描述的提交和回滚的代码示例. 此示例代码是基于前面章节中完成的环境和数据库设置编写的. 复制并将以下示例代码保存到:CommitAndRollback.java 中,编译并运行如下 ...

  4. MySQL事务部分回滚-回滚到指定保存点

    我们可以在mysql事务处理过程中定义保存点(SAVEPOINT),然后回滚到指定的保存点前的状态. 定义保存点,以及回滚到指定保存点前状态的语法如下. 定义保存点---SAVEPOINT 保存点名; ...

  5. spring5 源码深度解析----- 事务的回滚和提交(100%理解事务)

    上一篇文章讲解了获取事务,并且通过获取的connection设置只读.隔离级别等,这篇文章讲解剩下的事务的回滚和提交 回滚处理 之前已经完成了目标方法运行前的事务准备工作,而这些准备工作最大的目的无非 ...

  6. 难道你还不知道Spring之事务的回滚和提交的原理吗,这篇文章带你走进源码级别的解读。

    上一篇文章讲解了获取事务,并通过获取的connection设置只读,隔离级别等:这篇文章讲事务剩下的回滚和提交. 事务的回滚处理 之前已经完成了目标方法运行前的事务准备工作.而这些准备工作的最大目的无 ...

  7. spring + myBatis 常见错误:注解事务不回滚

    最近项目在用springMVC+spring+myBatis框架,在配置事务的时候发现一个事务不能回滚的问题. 刚开始配置如下:springMVC.xml配置内容: spring.xml配置内容 从上 ...

  8. Spring事务管理——回滚(rollback-for)控制

    探讨Spring事务控制中,异常触发事务回滚原理.文章进行了6种情况下的Spring事务是否回滚. 以下代码都是基于Spring与Mybatis整合,使用Spring声明式事务配置事务方法. 1.不捕 ...

  9. MySQL数据库的回滚失败(JAVA)

    这几天在学习MySQL数据的知识,有一个小测试,用来测试数据库的提交和回滚. 刚开始的时候真的没把这个当回事,按照正常的步骤来讲的话,如下所示,加载驱动,获取数据库的连接,并且把数据库的自动提交给关闭 ...

随机推荐

  1. MySQL 安全整理

    MySQL 安全整理 关闭外网的端口访问. 使用高位的端口号. 如果需要外网访问不给最高的权限. 如果需要外网访问也是绑定客户端. To be continued

  2. 23 模块 os sys pickle json

    一.   os模块 主要是针对操作系统的 用于文件操作 二.    sys 模块 模块的查找路径   sys.path 三   pickle 模块 1.  pickle.dumps(对象) 序列化  ...

  3. Oracle11g 密码延迟认证导致library cache lock的情况分析

    在 Oracle 11g 中,为了提升安全性,Oracle 引入了『密码延迟验证』的新特性.这个特性的作用是,如果用户输入了错误的密码尝试登录,那么随着登录错误次数的增加,每次登录前验证的时间也会增加 ...

  4. 洛谷 2234 [HNOI2002]营业额统计——treap(入门)

    题目:https://www.luogu.org/problemnew/show/P2234 学习了一下 treap 的写法. 学习材料:https://blog.csdn.net/litble/ar ...

  5. hanlp提取文本关键词的使用方法记录

    本文是csu_zipple 分享的关于使用hanlp汉语言处理包提取关键词的过程一个简单的记录分享.想要使用hanlp提取文本关键词的新手朋友们可以参考学习一下! 如何在一段文本之中提取出相应的关键词 ...

  6. 存储过程DT参数

    public static void TableValuedToDB(DataTable dt, string storedProcName, string TypeName) { using (Sq ...

  7. Pandas的使用(2)

    Pandas的使用(2) 1.新建一个空的DataFrame数据类型 total_price = pd.DataFrame() #新建一个空的DataFrame 2.向空的DataFrame中逐行添加 ...

  8. 【转】SQL Server日志文件过大 大日志文件清理方法 不分离数据库

    https://blog.csdn.net/slimboy123/article/details/54575592 还未测试 USE[master] GO ALTER DATABASE 要清理的数据库 ...

  9. 跟着未名学 - 录屏套件 Camtasia Studio

    目录 Camtasia Recorder. 1 Camtasia Studio.. 2 时间线... 2 渲染... 5 Camtasia MenuMaker. 6 Camtasia Play. 6 ...

  10. 关于sql 注入,感觉比较全的一篇文章

    原文链接 http://netsecurity.51cto.com/art/201705/538863.htm