数据库基础(4)事务

-- 事务

-- 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完全相同;

-- 事务四大特性
-- 原子性:事务包含的所有操作要么全部成功,要么全部失败,一个最小单位,不可再分割
-- 一致性:只包含成功的事务,事务中某个语句报错则整个事务不写入物理数据库
-- 隔离性:事务的执行不受其他事务干扰,对其他事务也没有任何影响;
-- 持久性:对于任意已提交的事务,系统保证该事务对数据库的改变不会损失,即使数据库出现故障.

你可能感兴趣的:(数据库基础(4)事务)