mysql 事务处理

创建表:
CREATE TABLE `role` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(50) DEFAULT NULL,
  `age` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=40006 DEFAULT CHARSET=utf-8;


创建存储过程:

每次执行插入,提交一次
DELIMITER $$
CREATE PROCEDURE load0(count INT UNSIGNED,iname varchar(50),iage INT)
BEGIN
DECLARE s INT UNSIGNED DEFAULT 1;
START TRANSACTION;
WHILE s<count DO
INSERT INTO role(name,age)VALUES(iname,iage);
SET s=s+1;
COMMIT;
END WHILE;
END$$
DELIMITER ;


跟load0,没有什么区别因为mysql默认开启自动提交
DELIMITER $$
CREATE PROCEDURE load1(count INT UNSIGNED,iname varchar(50),iage INT)
BEGIN
DECLARE s INT UNSIGNED DEFAULT 1;
START TRANSACTION;
WHILE s<count DO
INSERT INTO role(name,age)VALUES(iname,iage);
SET s=s+1;
END WHILE;
END$$
DELIMITER ;


所有插入一次提交:
DELIMITER $$
CREATE PROCEDURE load2(count INT UNSIGNED,iname varchar(50),iage INT)
BEGIN
DECLARE s INT UNSIGNED DEFAULT 1;
START TRANSACTION;
WHILE s<count DO
INSERT INTO role(name,age)VALUES(iname,iage);
SET s=s+1;
END WHILE;
COMMIT;
END$$
DELIMITER ;


执行存储过程:
call load0(10000,'jack',23);
[SQL]call load0(10000,'jack',23);

受影响的行: 0
时间: 26.520s
truncate table role;
[SQL]call load1(10000,'jack',23);

受影响的行: 1
时间: 0.483s
mysql> select * from information_schema.INNODB_TRX;
+--------+-----------+---------------------+-----------------------+------------------+------------+---------------------+-----------+---------------------+-------------------+-------------------+------------------+-----------------------+-----------------+-------------------+-------------------------+---------------------+-------------------+------------------------+----------------------------+---------------------------+---------------------------+------------------+----------------------------+
| trx_id | trx_state | trx_started         | trx_requested_lock_id | trx_wait_started | trx_weight | trx_mysql_thread_id | trx_query | trx_operation_state | trx_tables_in_use | trx_tables_locked | trx_lock_structs | trx_lock_memory_bytes | trx_rows_locked | trx_rows_modified | trx_concurrency_tickets | trx_isolation_level | trx_unique_checks | trx_foreign_key_checks | trx_last_foreign_key_error | trx_adaptive_hash_latched | trx_adaptive_hash_timeout | trx_is_read_only | trx_autocommit_non_locking |
+--------+-----------+---------------------+-----------------------+------------------+------------+---------------------+-----------+---------------------+-------------------+-------------------+------------------+-----------------------+-----------------+-------------------+-------------------------+---------------------+-------------------+------------------------+----------------------------+---------------------------+---------------------------+------------------+----------------------------+
| 27177  |[color=red] RUNNING[/color]   | [color=red]2016-07-29 15:53:43[/color] | NULL                  | NULL             |      10000 |                  21 | NULL      | NULL                |                 0 |                 0 |                1 |                   360 |               0 |              9999 |                       0 | REPEATABLE READ     |                 1 |                      1 | NULL                       |                         0 |                     10000 |                0 |                          0 |
+--------+-----------+---------------------+-----------------------+------------------+------------+---------------------+-----------+---------------------+-------------------+-------------------+------------------+-----------------------+-----------------+-------------------+-------------------------+---------------------+-------------------+------------------------+----------------------------+---------------------------+---------------------------+

我的计算机时间已经15:56了,事务还没有结束,前台调用存储过程虽然返回快,但后台事务还在运行
truncate table role;
call load2(10000,'jack',23);
[SQL]call load2(10000,'jack',23);

受影响的行: 0
时间: 0.462s
select * from information_schema.INNODB_TRX;

查看事务表为空;

从以上三个可以分析出,load0的执行时间较长,这是由于,每次提交,mysql都要写重做日志redo(ib_logfile0,1oad1虽然时间前台时间不长,但事务在后台运行,load3由于只做一次重做日志所以很快,当然我们是建议,不要在循环中事务提交,而是待所有语句执行完一起提交,最好不要在存储过程中开启事务,因为如果发生回滚,不知道出现什么错误,最好在代码中控制
如下:
try{
con.setautocommint(false)
con.commit();
}
catch(SQLException e){
con.rollback();
}


猜你喜欢

转载自donald-draper.iteye.com/blog/2314288