今天被问到了一个mysql自动事务提交的问题,就着这个问题对mysql的事务提交机制进行了一些研究,将测试的结果总结下。
一.mysql的自动事务提交设置
mysql中的自动事务提交是通过参数autocommit配置的,系统默认设置值为1,即开启状态
如果要关闭事务自动提交,执行下述SQL语句:
set autocommit=0;
二.各个事务提交状态与显式事务提交的关系
以student表为例说明,建表语句如下:
CREATE TABLE `student` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) DEFAULT NULL,
`age` int(11) DEFAULT NULL,
`clazz_id` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
)
1.在autocommit=0,即自动事务提交状态关闭的情况下,必须要执行commit语句,更新才做才会保存到数据库;
如果sql语句如下:
set autocommit=0;#关闭事务的自动提交
insert into student(name,age,clazz_id) values('zhangsan',28,3);
则执行上述的语句后,查询数据库,发现并没有姓名为zhangsan的记录,说明insert操作并没有保存到数据库。需要执行commit才会真正保存到数据库。
set autocommit=0;#关闭事务的自动提交
insert into student(name,age,clazz_id) values('zhangsan',28,3);
commit;
执行上面的sql后,查询数据库可以查询到zhangsan的记录,执行commit操作后,insert操作才保存到数据库。
对于多条insert的操作:
set autocommit=0;#关闭事务的自动提交
insert into student(name,age,clazz_id) values('lisi',28,3);
insert into student(name,age,clazz_id) values('wangwu',28,4);
commit;
数据库也可以查询出记录,没有begin语句,只有commit语句,这里的多条insert是不是为同一个事务有待考察。
2.在autocommit=1,即自动事务提交状态为开启的情况下,不执行commit语句,更改也会保存到数据库,并且各条更改操作是独立的事务,而不是同一个事务。
set autocommit=1;#开启事务自动提交
insert into student(name,age,clazz_id) values('zhaoliu',28,3);
执行上述sql后,查询数据库zaholiu的记录已经存在,说明开启自动事务提交情况下,不显式执行commit提交,mysql也会隐式的帮我们提交事务。
set autocommit=1;#开启事务自动提交
insert into student(name,age,clazz_id) values('tianqi',28,4);
insert into student(name,age,clazz_id) values('wangba',28,3);
执行语句中有多个更新操作时,上述的两个insert操作是两个独立的事务,即当第一条insert语句成功,第二条insert语句执行失败的情况下,第一条sql语句不会回滚,数据库中可以查询到tianqi的记录。
到这里总结一:在没有begin,即没有手动开启事务的情况下,autocommit=0时,commit手动提交才会保存到数据库;autocommit=1时,数据库会自动的将更新保存到数据库。
3.考虑手动开启事务的情况,即出现begin的情况
autocommit=0的情况
set autocommit=0;#关闭事务的自动提交
begin;
insert into student(name,age,clazz_id) values('lili',28,3);
执行后数据库查询不到lili记录,手动开启事务后,不执行commit更改不会保存到数据库
set autocommit=0;#关闭事务的自动提交
begin;
insert into student(name,age,clazz_id) values('lili',28,3);
commit;
数据库查询到lili记录,说明autocommit=0情况下,有begin必须有commit才会提交。
autocommit=1的情况
set autocommit=1;#开启事务自动提交
begin;
insert into student(name,age,clazz_id) values('jia',28,4);
数据库查询不到记录,手动开启事务后,不执行commit更改不会保存到数据库。
set autocommit=1;#开启事务自动提交
begin;
insert into student(name,age,clazz_id) values('jia',28,4);
commit;
数据库可以查询到记录,autocommit=1情况下,也要commit才会保存到数据库
总结第二点:在手动开启事务的情况下(即出现begin),不论自动提交状态是关闭还是打开,都需要commit提交更改才会保存到数据库。