欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

关于MySQL中的事务、回滚(rollback)、提交(commit)

程序员文章站 2022-07-05 08:15:09
...

0 场景

需要连续对同一数据表进行增删改操作时,我们会分别执行多条sql语句。
此时可能会出现两类问题:

  1. 所有的语句执行完成后,发现其中一句执行错了
  2. 某一句执行完成后,后悔了想要重新执行

遇到上述问题,能够时光倒流和吃后悔药吗?
MySQL的Innodb引擎中,为我们提供了事务功能,事务通过rollback和commit来操作。

1 配置/开始事务

1.1 配置事务

MySQL客户端shell关于“自动提交”和“事务”的参数是autocommit,默认值是1,即默认开启自动提交,事务不开启。
所以当你每次使用insertdeleteupdate等语句的时候,数据表实际就会完成更改。
修改配置则有两种方式。

1.1.1 修改my.cnf配置文件

[mysqld]  
# 新增如下内容,预连接选项
init_connect='SET autocommit=0'

注意:

连接mysql用户的权限不能大于启动mysql的用户的权限,不然init_connect='SET autocommit=0’根本不会启作用,也不会报任何错误

1.1.2 设置环境变量

此种方式开启的事务仅仅对本次连接和本次连接开启的客户端shell有效,关闭后再开启则恢复配置文件所定义的或者默认配置的状态。
先通过以下两种方式查询

mysql> show variables like 'autocommit';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| autocommit    | ON    |
+---------------+-------+
1 row in set (0.00 sec)

mysql> select @@autocommit;
+--------------+
| @@autocommit |
+--------------+
|            1 |
+--------------+
1 row in set (0.00 sec)

从上面的查询结果可以看到事务是关闭的,每次执行增删改都会自动提交所操作的语句。
执行如下语句:

mysql> set autocommit=off;
Query OK, 0 rows affected (0.00 sec)

发现自动提交关闭了,说明现在可以使用事务了。

mysql> show variables like 'autocommit';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| autocommit    | OFF   |
+---------------+-------+
1 row in set (0.00 sec)

mysql> select @@autocommit;
+--------------+
| @@autocommit |
+--------------+
|            0 |
+--------------+
1 row in set (0.00 sec)

注意:

直接退出客户端,事务中的变更不会默认保存

1.2 直接开始事务

除了配置开启事务,也可以直接使用start transaction开启事务。
注意:

这种方式在当你使用commit或者rollback后,事务就结束了
再次进入事务状态需要再次start transaction

2 使用事务

2.1 修改环境变量autocommit后

autocommit=OFF时,每次修改后,必须commit后更改才能生效。否则只在shell内是已经改变的状态。

2.2 使用transaction时

mysql> select * from test_sub;
+-------------+------+---------------+
| test_sub_id | name | uid           |
+-------------+------+---------------+
|           1 | A    | ert456yhrty   |
|           2 | B    | ert456y56hrty |
|           3 | C    | ert456y56hrty |
+-------------+------+---------------+
3 rows in set (0.00 sec)

mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)

mysql> insert into test_sub(name,uid) values('D','rteuio56syt');
Query OK, 1 row affected (0.04 sec)

mysql> select * from test_sub;
+-------------+------+---------------+
| test_sub_id | name | uid           |
+-------------+------+---------------+
|           1 | A    | ert456yhrty   |
|           2 | B    | ert456y56hrty |
|           3 | C    | ert456y56hrty |
|           4 | D    | rteuio56syt   |
+-------------+------+---------------+
4 rows in set (0.00 sec)

mysql> rollback;
Query OK, 0 rows affected (0.13 sec)

mysql> select * from test_sub;
+-------------+------+---------------+
| test_sub_id | name | uid           |
+-------------+------+---------------+
|           1 | A    | ert456yhrty   |
|           2 | B    | ert456y56hrty |
|           3 | C    | ert456y56hrty |
+-------------+------+---------------+
3 rows in set (0.00 sec)

如果已经commit,就无法继续提交了。

事务中的rollback和commit的使用比较简单,这里就不详细的叙述了。

参考:https://blog.csdn.net/w_linux/article/details/79666086 (MySQL——事务(Transaction)详解)
参考:https://blog.csdn.net/lgd200008/article/details/79056645 (MYSQL关于 autocommit 设置)
参考:https://blog.csdn.net/qq_26941173/article/details/77872038 (mysql中set autocommit=0与start transaction区别)
参考:https://www.cnblogs.com/manzb/p/6547866.html (Mysql 关闭自动commit)