• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • MsSql
  • Mysql
  • oracle
  • MariaDB
  • DB2
  • SQLite
  • PostgreSQL
  • MongoDB
  • Redis
  • Access
  • 数据库其它
  • sybase
  • HBase
您的位置:首页 > 数据库 >Mysql > MySQL Innodb事务编程问题和处理

MySQL Innodb事务编程问题和处理

作者:匿名 字体:[增加 减小] 来源:互联网 时间:2018-12-05

匿名通过本文主要向大家介绍了MySQL,Innodb,事务编程等相关知识,希望本文的分享对您有所帮助
1.在循环中提交的问题

很多开发人员非常喜欢在循环中进行事务提交,下面演示一个他们经常写的一个存储过程示例,如下所示:

DROP PROCEDURE IF EXISTS load1;CREATE PROCEDURE load1(count INT UNSIGNED)BEGIN
   DECLARE s INT UNSIGNED DEFAULT 1;
   DECLARE c CHAR(80) DEFAULT REPEAT('a',80);   WHILE s <= count DO
      INSERT INTO t1 select NULL,c;
      COMMIT;      SET s=s+1;   END WHILE;END;

在上面的例子中,是否加上commit命令并不是关键。由于MySQL innodb的存储引擎默认为自动提交,因此去掉存储过程中的commit结果是一样的。如下所示,下面也是另一个容易被开发人员忽视的问题:

DROP PROCEDURE IF EXISTS load2; CREATE PROCEDURE load2(count INT UNSIGNED)BEGIN
   DECLARE s INT UNSIGNED DEFAULT 1;
   DECLARE c CHAR(80) DEFAULT REPEAT('a',80);   WHILE s <= count DO
      INSERT INTO t1 select NULL,c;      SET s=s+1;   END WHILE;END;

不论上面哪个存储过程,当发生错误时,数据库会停留在一个未知的位置。例如我们要插入10000条数据,但是在插入5000条时发生了错误,然而这5000条已经存放在了数据库中,我们如何处理?另外一个是性能问题,上面的两个存储过程都不会比下面的这个存储过程快,因为下面这个是将insert放在了一个事务中:

DROP PROCEDURE IF EXISTS load3; CREATE PROCEDURE load3(count INT UNSIGNED)BEGIN
   DECLARE s INT UNSIGNED DEFAULT 1;
   DECLARE c CHAR(80) DEFAULT REPEAT('a',80);
   START TRANSACTION;   WHILE s <= count DO
      INSERT INTO t1 select NULL,c;      SET s=s+1;   END WHILE;
   COMMIT;END;

对于上面三个存储过程,我们分别插入100万数据来比较执行时间,如下所示,显然可以看到第三种方法要快很多,这是因为每次提及都要写一次重做日志,所以load1和load2实际写了100万次重做日志。对于存储过程load3,我们只写了1次重做日志。

先准备一个测试表

CREATE TABLE `t1` (`id` int NOT NULL AUTO_INCREMENT ,`name` varchar(500) NULL ,
PRIMARY KEY (`id`)
) ;

执行测试

09:50:44 test> call load1(1000000);
Query OK, 0 rows affected (1 min 4.90 sec)09:54:23 test> truncate table t1;
Query OK, 0 rows affected (0.05 sec)09:54:25 test> call load2(1000000);
Query OK, 1 row affected (1 min 3.38 sec)09:55:32 test> truncate table t1;
Query OK, 0 rows affected (0.20 sec)09:55:58 test> call load3(1000000);
Query OK, 0 rows affected (33.90 sec)

对于第二个存储过程load2,我们也可以人为的开启下事务,同样可以达到存储过程load3的效果,执行时间如下所示:

09:57:42 test> begin;
Query OK, 0 rows affected (0.00 sec)09:57:46 test> call load2(1000000);
Query OK, 1 row affected (34.08 sec)09:58:26 test> commit;
Query OK, 0 rows affected (0.76 sec)

2.关于使用自动提交

在一些特殊场景下,有时候自动提交不一定是个好的事情, 如我们上面讲到的循环提交的问题,MySQL数据库默认是自动提交(autocommit)。可以通过如下方式来改变MySQL的提交方式:

10:35:34 test> SET AUTOCOMMIT=0;
Query OK, 0 rows affected (0.00 sec)

也可以使用START TRANSATION或者BEGIN显示的开启一个事务。MySQL会自动执行

SET AUTOCOMMIT=0,并在COMMIT或ROLLBACK结束一个事务后执行SET AUTOCOMMIT=1 。

3.使用自动回滚处理异常 当存储过程发生异常的时候怎么办,Innodb存储引擎支持通过一个HANDLER来进行事务的自动回滚操作。如在存储过程中发生错误会自动进行回滚操作。如下面一个示例:

CREATE PROCEDURE sp_auto_rollback_demo()BEGIN
   DECLARE EXIT HANDLER FOR SQLEXCEPTION ROLLBACK;
   START TRANSACTION;
   INSERT INTO b select 1;
   INSERT INTO b select 2;
   INSERT INTO b select 1;
   INSERT INTO b select 3;
   COMMIT;END;

测试表如下

CREATE TABLE `b` (  `a` int(11) NOT NULL DEFAULT '0',
  PRIMARY KEY (`a`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

执行上面的存储过程,因此会在插入第二个记录1时发生错误,但是因为启用了自动回滚操作,这个存储过程执行结果如下:

10:09:46 test> call sp_auto_rollback_demo;
Query OK, 0 rows affected (0.01 sec)10:10:04 test> select * from b;Empty set (0.00 sec)

看起来没有问题,运行比较正常,但是在执行sp_auto_rollback_demo的时候是执行成功了还是失败了?对此,我们可以进行如下处理,示例如下:

DROP PROCEDURE IF EXISTS sp_auto_rollback_demo;CREATE PROCEDURE sp_auto_rollback_demo()BEGIN
   DECLARE EXIT HANDLER FOR SQLEXCEPTION BEGIN ROLLBACK; SELECT -1; END;
   START TRANSACTION;
   INSERT INTO b select 1;
   INSERT INTO b select 2;
   INSERT INTO b select 1;
   INSERT INTO b select 3;
   COMMIT;
   SELECT 1;END;

当发生错误时,先回滚然后返回-1,表示运行发生了错误。返回1表示运行正常。运行结果如下:

10:16:19 test> call sp_auto_rollback_demo\G*************************** 1. row ***************************-1: -1
1 row in set (0.00 sec)
Query OK, 0 rows affected (0.01 sec)
10:16:35 test> select * from b;
Empty set (0.00 sec)

以上就是MySQL Innodb事务编程问题和处理的内容,更多相关内容请关注微课江湖()!

分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • 分享下mysql各个主要版本之间的差异
  • MySQL essential版本和普通版本有什么区别?
  • redhat 5.4下安装MYSQL全过程
  • 如何用SQL命令查看Mysql数据库大小
  • 解析mysql中如何获得数据库的大小
  • 解析mysql修改为utf8后仍然有乱码的问题
  • 5个常用的MySQL数据库管理工具详细介绍
  • 解析在MySQL里创建外键时ERROR 1005的解决办法
  • 解析远程连接管理其他机器上的MYSQL数据库
  • mysql 精简过程(删除一些文件)

相关文章

  • 2018-12-05mysql insert if not exists防止插入重复记录的方法
  • 2018-12-05MySQL OOM 系列三 摆脱MySQL被Kill的厄运_MySQL
  • 2017-05-11mysql 按中文字段排序
  • 2018-12-05六条比较有用的MySQL数据库操作的SQL语句小结
  • 2018-12-05MySQL之—重连,连接丢失的代码实例详解
  • 2018-12-05Mysql-索引数据排序
  • 2018-12-05rac rman备份因归档不可访问出错RMAN-06059 RMAN-03002 ORA-1962
  • 2017-05-11MYSQL数据表损坏的原因分析和修复方法小结(推荐)
  • 2017-05-11Mysql 导入导出csv 中文乱码问题的解决方法
  • 2018-12-05SQLserver 数据库危险存储过程删除与恢复方法

文章分类

  • MsSql
  • Mysql
  • oracle
  • MariaDB
  • DB2
  • SQLite
  • PostgreSQL
  • MongoDB
  • Redis
  • Access
  • 数据库其它
  • sybase
  • HBase

最近更新的内容

    • tomcat-dbcp数据库连接池配置以及使用时候的一些坑
    • RHEL6.2编译安装MySQL 5.6.16过程分享
    • mysql基本操作有哪些
    • MySQL正则表达式入门教程
    • mysql 精简过程(删除一些文件)
    • MYSQL创建函数出错如何解决
    • 从创建数据库到存储过程与用户自定义函数的小感
    • pymysql 操作数据库
    • mysql 模糊搜索的方法介绍
    • mysql命令行还原phpMyAdmin导出的含有中文的SQL文件

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有