MySQL 事务最全详解( 二 )


多种存储引擎时事务的处理方式
根据上面事务使用的条件,我们可以得知有的存储引擎是不支持事务的,例如 MyISAM 存储引擎就不支持 。那如果在一个事务中使用了事务性的存储引擎和非事务性的存储,提交是可以正常进行,但是回滚非事务性的存储引擎则会显示响应的错误信息,具体信息和存储引擎有关.
如何使用事务
MySQL 中事务隐式开启的,也就是说,一个 sql 语句就是一个事务,当 sql 语句执行完毕,事务就提交了 。在演示的过程中,我们显式开启.
MySQL 中的自动提交
上面提到了 MySQL 中事务是隐式开启的,则代表我们每一个 sql 是自动提交的,需要关闭则需要设置 autocommit 选项.
// 查看autocommit配置值(1或者ON则表示开启)
mysql root@127.0.0.1:(none)> show variables like '%autocommit%';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| autocommit | ON |
+---------------+-------+
1 row in set
Time: 0.018s
// 设置autocommit配置值
mysql root@127.0.0.1:(none)> set autocommit = 0;
Query OK, 0 rows affected
Time: 0.000s
mysql root@127.0.0.1:(none)> show variables like '%autocommit%';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| autocommit | OFF |
+---------------+-------+
1 row in set
Time: 0.013s
1. 表结构如下
mysql root@127.0.0.1:test> desc user;
+-------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | <null> | auto_increment |
| name | varchar(255) | YES | | <null> | |
| age | int(2) | YES | | <null> | |
+-------+--------------+------+-----+---------+----------------+
3 rows in set
Time: 0.013s
SQL 语句
CREATE TABLE `test`.`Untitled` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
`age` int(2) NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
2. 使用事务
MySQL 实现事务
下面的代码,我们主要做了如下几个操作
a. 开启事务
b. 修改数据
c. 查询数据是否改变
d. 数据回滚
e. 再次查询数据,发现数据变回修改之前的状态
f. 修改数据
g. 事务提交
h. 查询数据,发现数据变为最后一次修改的状态
i. 尝试事务回滚
j. 查询验证是否被回滚了,发现数据还是为最后一次修改的状态,事务回滚失败
// 我们先查看表中的数据,id为1的age字段是12
mysql root@127.0.0.1:test> select * from user;
+----+------+-----+
| id | name | age |
+----+------+-----+
| 1 | 张三 | 12 |
| 2 | 李四 | 15 |
+----+------+-----+
2 rows in set
Time: 0.013s
// 开启事务
mysql root@127.0.0.1:test> begin;
Query OK, 0 rows affected
Time: 0.001s
// 将id为1的age字段改为10
mysql root@127.0.0.1:test> update user set age=10 where id=1;
Query OK, 1 row affected
Time: 0.001s
// 再次查询数据时,发现数据改为修改后的值
mysql root@127.0.0.1:test> select * from user;
+----+------+-----+
| id | name | age |
+----+------+-----+
| 1 | 张三 | 10 |
| 2 | 李四 | 15 |
+----+------+-----+
2 rows in set
Time: 0.012s
// 此时我们进行回滚操作
mysql root@127.0.0.1:test> rollback;
Query OK, 0 rows affected
Time: 0.001s
// 再次查询发现数据回到最初状态
mysql root@127.0.0.1:test> select * from user;
+----+------+-----+
| id | name | age |
+----+------+-----+
| 1 | 张三 | 12 |
| 2 | 李四 | 15 |
+----+------+-----+
2 rows in set
Time: 0.019s
// 我们再次对数据进行修改
mysql root@127.0.0.1:test> update user set age=15 where id=1;
Query OK, 1 row affected
Time: 0.001s
// 此时将事务进行提交
mysql root@127.0.0.1:test> commit;
Query OK, 0 rows affected
Time: 0.000s
// 发现此时的数据变为我们最终提交的值
mysql root@127.0.0.1:test> select * from user;
+----+------+-----+
| id | name | age |
+----+------+-----+
| 1 | 张三 | 15 |
| 2 | 李四 | 15 |
+----+------+-----+
2 rows in set
Time: 0.012s
// 我们尝试用刚才回滚的方式进行还原数据


推荐阅读