0


[MySQL][事务管理][中][事务常见操作方式]详细讲解

目录


0.准备工作

# 为了便于演示,将mysql的默认隔离级别设置成读未提交。
mysql> set global transaction isolation level READ UNCOMMITTED;

# 需要重启终端,进行查看
mysql> select @@tx_isolation;
+------------------+
| @@tx_isolation   |
+------------------+
| READ-UNCOMMITTED |
+------------------+
  • 简单银行用户表create table if not exists account( id int primary key, name varchar(50) not null default '', blance decimal(10,2) not null default 0.0)ENGINE=InnoDB DEFAULT CHARSET=UTF8;

1.操作演示

  • 正常演示 - 证明事务的开始与回滚-- 查看事务是否自动提交。故意设置成自动提交,看看该选项是否影响beginmysql> show variables like 'autocommit'; +---------------+-------+| Variable_name | Value |+---------------+-------+| autocommit | ON |+---------------+-------+mysql> start transaction; -- 开始一个事务begin也可以,推荐beginmysql> savepoint save1; -- 创建一个保存点save1mysql> insert into account values (1, '张三', 100); -- 插入一条记录mysql> savepoint save2; -- 创建一个保存点save2mysql> insert into account values (2, '李四', 10000); -- 再插入一条记录mysql> select * from account; -- 两条记录都在了+----+--------+----------+| id | name | blance |+----+--------+----------+| 1 | 张三 | 100.00 || 2 | 李四 | 10000.00 |+----+--------+----------+mysql> rollback to save2; -- 回滚到保存点save2mysql> select * from account; -- 一条记录没有了+----+--------+--------+| id | name | blance |+----+--------+--------+| 1 | 张三 | 100.00 |+----+--------+--------+mysql> rollback; -- 直接rollback,回滚在最开始mysql> select * from account; -- 所有刚刚的记录没有了Empty set (0.00 sec)
  • 非正常演示1 - 证明未commit,客户端崩溃,MySQL自动会回滚(隔离级别设置为读未提交)-- 终端Amysql> select * from account; -- 当前表内无数据Empty set (0.00 sec)mysql> show variables like 'autocommit'; -- 依旧自动提交+---------------+-------+| Variable_name | Value |+---------------+-------+| autocommit | ON |+---------------+-------+mysql> begin; --开启事务mysql> insert into account values (1, '张三', 100); -- 插入记录mysql> select * from account; --数据已经存在,但没有commit,此时同时查看终端B+----+--------+--------+| id | name | blance |+----+--------+--------+| 1 | 张三 | 100.00 |+----+--------+--------+mysql> Aborted -- ctrl + \ 异常终止MySQL--终端Bmysql> select * from account; --终端A崩溃前+----+--------+--------+| id | name | blance |+----+--------+--------+| 1 | 张三 | 100.00 |+----+--------+--------+mysql> select * from account; --数据自动回滚Empty set (0.00 sec)
  • 非正常演示2 - 证明commit了,客户端崩溃,MySQL数据不会在受影响,已经持久化--终端 Amysql> show variables like 'autocommit'; -- 依旧自动提交+---------------+-------+| Variable_name | Value |+---------------+-------+| autocommit | ON |+---------------+-------+mysql> select * from account; -- 当前表内无数据Empty set (0.00 sec)mysql> begin; -- 开启事务mysql> insert into account values (1, '张三', 100); -- 插入记录mysql> commit; --提交事务mysql> Aborted -- ctrl + \ 异常终止MySQL--终端 Bmysql> select * from account; --数据存在了,所以commit的作用是将数据持久化到MySQL中+----+--------+--------+| id | name | blance |+----+--------+--------+| 1 | 张三 | 100.00 |+----+--------+--------+
  • 非正常演示3 - 对比试验,证明begin操作会自动更改提交方式,不会受MySQL是否自动提交影响-- 终端 Amysql> select *from account; --查看历史数据+----+--------+--------+| id | name | blance |+----+--------+--------+| 1 | 张三 | 100.00 |+----+--------+--------+mysql> show variables like 'autocommit'; --查看事务提交方式+---------------+-------+| Variable_name | Value |+---------------+-------+| autocommit | ON |+---------------+-------+mysql> set autocommit=0; --关闭自动提交mysql> show variables like 'autocommit'; --查看关闭之后结果+---------------+-------+| Variable_name | Value |+---------------+-------+| autocommit | OFF |+---------------+-------+mysql> begin; --开启事务mysql> insert into account values (2, '李四', 10000); --插入记录mysql> select *from account; --查看插入记录,同时查看终端B+----+--------+----------+| id | name | blance |+----+--------+----------+| 1 | 张三 | 100.00 || 2 | 李四 | 10000.00 |+----+--------+----------+mysql> Aborted --再次异常终止-- 终端Bmysql> select * from account; --终端A崩溃前+----+--------+----------+| id | name | blance |+----+--------+----------+| 1 | 张三 | 100.00 || 2 | 李四 | 10000.00 |+----+--------+----------+mysql> select * from account; --终端A崩溃后,自动回滚+----+--------+--------+| id | name | blance |+----+--------+--------+| 1 | 张三 | 100.00 |+----+--------+--------+
  • 非正常演示4 - 证明单条 SQL 与事务的关系-- 实验一-- 终端Amysql> select * from account;+----+--------+--------+| id | name | blance |+----+--------+--------+| 1 | 张三 | 100.00 |+----+--------+--------+mysql> show variables like 'autocommit';+---------------+-------+| Variable_name | Value |+---------------+-------+| autocommit | ON |+---------------+-------+mysql> set autocommit=0; --关闭自动提交mysql> insert into account values (2, '李四', 10000); --插入记录mysql> select *from account; --查看结果,已经插入。此时可以在查看终端B+----+--------+----------+| id | name | blance |+----+--------+----------+| 1 | 张三 | 100.00 || 2 | 李四 | 10000.00 |+----+--------+----------+mysql> ^DBye --ctrl + \ or ctrl + d,终止终端-- 终端Bmysql> select * from account; --终端A崩溃前+----+--------+----------+| id | name | blance |+----+--------+----------+| 1 | 张三 | 100.00 || 2 | 李四 | 10000.00 |+----+--------+----------+mysql> select * from account; --终端A崩溃后+----+--------+--------+| id | name | blance |+----+--------+--------+| 1 | 张三 | 100.00 |+----+--------+--------+-- 实验二-- 终端Amysql> show variables like 'autocommit'; --开启默认提交+---------------+-------+| Variable_name | Value |+---------------+-------+| autocommit | ON |+---------------+-------+mysql> select * from account;+----+--------+--------+| id | name | blance |+----+--------+--------+| 1 | 张三 | 100.00 |+----+--------+--------+mysql> insert into account values (2, '李四', 10000);mysql> select *from account; --数据已经插入+----+--------+----------+| id | name | blance |+----+--------+----------+| 1 | 张三 | 100.00 || 2 | 李四 | 10000.00 |+----+--------+----------+mysql> Aborted --异常终止-- 终端Bmysql> select * from account; --终端A崩溃前+----+--------+----------+| id | name | blance |+----+--------+----------+| 1 | 张三 | 100.00 || 2 | 李四 | 10000.00 |+----+--------+----------+mysql> select * from account; --终端A崩溃后,并不影响,已经持久化。autocommit起作用+----+--------+----------+| id | name | blance |+----+--------+----------+| 1 | 张三 | 100.00 || 2 | 李四 | 10000.00 |+----+--------+----------+

2.总结

  • 只要输入begin或者start transaction,事务便必须要通过commit提交,才会持久化,与是否设置set autocommit无关
  • 事务可以手动回滚,同时,当操作异常,MySQL会自动回滚
  • 对于 InnoDB 每一条 SQL 语言都默认封装成事务,自动提交(select有特殊情况,因为 MySQL 有 MVCC)
  • 从上面的例子,能看到事务本身的原子性(回滚),持久性(commit)

3.事务操作注意事项

  • 如果没有设置保存点,也可以回滚,只能回滚到事务的开始。直接使用 rollback(前提是事务还没有提交)
  • 如果一个事务被提交了(commit),则不可以回退(rollback)
  • 可以选择回退到哪个保存点
  • InnoDB 支持事务, MyISAM 不支持事务
  • 开始事务可以使 start transaction 或者 begin


本文转载自: https://blog.csdn.net/qq_37281656/article/details/140564788
版权归原作者 DieSnowK 所有, 如有侵权,请联系我们删除。

“[MySQL][事务管理][中][事务常见操作方式]详细讲解”的评论:

还没有评论