-- 事务
-- mysql中,事务其实是一个最小的不可分割的工作单元,事务能保证一个业务的完整性.
-- 默认事务是开启(自动提交)
-- 即当我们去执行一个sql语句的时候,效果会立即体现出来,且不能回滚
mysql> select @@autocommit;
+--------------+
| @@autocommit |
+--------------+
| 1 |
+--------------+
1 row in set (0.00 sec)
-- 事务回滚:撤销sql语句的执行效果
rollback;
-- 创建一个数据库和表
create database bank
use bank;
create table user(
id int primary key auto_increment,
name varchar(20),
fund int
);
INSERT INTO user (name,fund) VALUES('张三',20000),('李四',4000);
mysql> select * from user;
+----+--------+-------+
| id | name | fund |
+----+--------+-------+
| 1 | 张三 | 20000 |
| 2 | 李四 | 4000 |
+----+--------+-------+
2 rows in set (0.00 sec)
-- 插入新的数据
INSERT INTO user (name,fund) VALUES('周润发',2000000);
mysql> select * from user;
+----+-----------+---------+
| id | name | fund |
+----+-----------+---------+
| 1 | 张三 | 20000 |
| 2 | 李四 | 4000 |
| 3 | 周润发 | 2000000 |
+----+-----------+---------+
3 rows in set (0.00 sec)
-- 尝试撤销 rollback
mysql> rollback;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from user;
+----+-----------+---------+
| id | name | fund |
+----+-----------+---------+
| 1 | 张三 | 20000 |
| 2 | 李四 | 4000 |
| 3 | 周润发 | 2000000 |
+----+-----------+---------+
3 rows in set (0.00 sec)
-- 发现无变化
-- 将事务设置为0,即关闭
mysql> set autocommit=0;
Query OK, 0 rows affected (0.00 sec)
--上面的操作关闭了 mysql 的自动提交 (commit)
mysql> select @@autocommit;
+--------------+
| @@autocommit |
+--------------+
| 0 |
+--------------+
1 row in set (0.00 sec)
-- 设置完成后 再插入条数据
mysql> INSERT INTO user (name,fund) VALUES('周星星',8880000);
Query OK, 1 row affected (0.00 sec)
mysql> select * from user;
+----+-----------+---------+
| id | name | fund |
+----+-----------+---------+
| 1 | 张三 | 20000 |
| 2 | 李四 | 4000 |
| 3 | 周润发 | 2000000 |
| 4 | 周星星 | 8880000 |
+----+-----------+---------+
4 rows in set (0.00 sec)
-- 尝试撤销
mysql> rollback;
Query OK, 0 rows affected (0.03 sec)
mysql> select * from user;
+----+-----------+---------+
| id | name | fund |
+----+-----------+---------+
| 1 | 张三 | 20000 |
| 2 | 李四 | 4000 |
| 3 | 周润发 | 2000000 |
+----+-----------+---------+
3 rows in set (0.00 sec)
-- 撤销成功
-- 事务(自动提交)关闭后,操作完所查看到的表其实是一张虚拟的表,真正的表里并没有改动
-- 想要改动真正的表,需在工作的最后 commit;
-- 重新插入数据
mysql> INSERT INTO user (name,fund) VALUES('周星星',8880000);
Query OK, 1 row affected (0.00 sec)
mysql> select * from user;
+----+-----------+---------+
| id | name | fund |
+----+-----------+---------+
| 1 | 张三 | 20000 |
| 2 | 李四 | 4000 |
| 3 | 周润发 | 2000000 |
| 5 | 周星星 | 8880000 |
+----+-----------+---------+
4 rows in set (0.00 sec)
-- 确定数据,修改真正的表
mysql> commit;
Query OK, 0 rows affected (0.03 sec)
-- 尝试撤销
mysql> rollback;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from user;
+----+-----------+---------+
| id | name | fund |
+----+-----------+---------+
| 1 | 张三 | 20000 |
| 2 | 李四 | 4000 |
| 3 | 周润发 | 2000000 |
| 5 | 周星星 | 8880000 |
+----+-----------+---------+
4 rows in set (0.00 sec)
-- 撤销失败
-- 张三给李四转账2000
update user set fund = fund +2000 where name = '李四';
update user set fund = fund -2000 where name = '张三';
mysql> select * from user;
+----+-----------+---------+
| id | name | fund |
+----+-----------+---------+
| 1 | 张三 | 18000 |
| 2 | 李四 | 6000 |
| 3 | 周润发 | 2000000 |
| 5 | 周星星 | 8880000 |
+----+-----------+---------+
4 rows in set (0.00 sec)
-- 假设转账过程中出现什么问题,就可以 rollback;
mysql> rollback;
Query OK, 0 rows affected (0.03 sec)
mysql> select * from user;
+----+-----------+---------+
| id | name | fund |
+----+-----------+---------+
| 1 | 张三 | 20000 |
| 2 | 李四 | 4000 |
| 3 | 周润发 | 2000000 |
| 5 | 周星星 | 8880000 |
+----+-----------+---------+
4 rows in set (0.00 sec)
-- 事务给了我们一个返回的机会
-- 恢复默认 即恢复自动提交
mysql> set autocommit=1;
Query OK, 0 rows affected (0.00 sec)
mysql> select @@autocommit;
+--------------+
| @@autocommit |
+--------------+
| 1 |
+--------------+
1 row in set (0.00 sec)
-- 此外,还可以通过
-- begin;
-- 或
-- start transaction;
-- 手动创建一个事务
-- 张三重新给李四转账2000
-- 注意 我已经将自动提交开启
begin;
update user set fund = fund +2000 where name = '李四';
update user set fund = fund -2000 where name = '张三';
mysql> select * from user;
+----+-----------+---------+
| id | name | fund |
+----+-----------+---------+
| 1 | 张三 | 18000 |
| 2 | 李四 | 6000 |
| 3 | 周润发 | 2000000 |
| 5 | 周星星 | 8880000 |
+----+-----------+---------+
4 rows in set (0.00 sec)
-- 尝试撤销
mysql> rollback;
Query OK, 0 rows affected (0.04 sec)
mysql> select * from user;
+----+-----------+---------+
| id | name | fund |
+----+-----------+---------+
| 1 | 张三 | 20000 |
| 2 | 李四 | 4000 |
| 3 | 周润发 | 2000000 |
| 5 | 周星星 | 8880000 |
+----+-----------+---------+
4 rows in set (0.00 sec)
-- 撤销成功了
-- 张三又又重新给李四转账2000
update user set fund = fund +2000 where name = '李四';
update user set fund = fund -2000 where name = '张三';
mysql> select * from user;
+----+-----------+---------+
| id | name | fund |
+----+-----------+---------+
| 1 | 张三 | 18000 |
| 2 | 李四 | 6000 |
| 3 | 周润发 | 2000000 |
| 5 | 周星星 | 8880000 |
+----+-----------+---------+
4 rows in set (0.00 sec)
-- 这次我让张三转账成功 commit;
mysql> commit;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from user;
+----+-----------+---------+
| id | name | fund |
+----+-----------+---------+
| 1 | 张三 | 18000 |
| 2 | 李四 | 6000 |
| 3 | 周润发 | 2000000 |
| 5 | 周星星 | 8880000 |
+----+-----------+---------+
4 rows in set (0.00 sec)
mysql> rollback;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from user;
+----+-----------+---------+
| id | name | fund |
+----+-----------+---------+
| 1 | 张三 | 18000 |
| 2 | 李四 | 6000 |
| 3 | 周润发 | 2000000 |
| 5 | 周星星 | 8880000 |
+----+-----------+---------+
4 rows in set (0.00 sec)
-- commit以后,就撤销不了了 张三终于成功了 恭喜
-- start transaction使用方法与begin完全相同;
-- 事务四大特性
-- 原子性:事务包含的所有操作要么全部成功,要么全部失败,一个最小单位,不可再分割
-- 一致性:只包含成功的事务,事务中某个语句报错则整个事务不写入物理数据库
-- 隔离性:事务的执行不受其他事务干扰,对其他事务也没有任何影响;
-- 持久性:对于任意已提交的事务,系统保证该事务对数据库的改变不会损失,即使数据库出现故障.