目录
1.2 和事务相关的语句只有:DML语句。(insert,delete,update)
1.3 假设所有的业务都能使用1条DML语句搞定,还需要事务机制吗?
🎈演示:mysql中的事务是支持自动提交的,只要执行一条DML语句,则提交一次
🎈演示:使用start transaction关闭自动提交机制
1. 事务(Transaction)的概述
1.1 什么是事务
一个事务是一个完整的业务逻辑单元,不可再分。
比如:银行账户转账,从 act-001 账户向 atc-002 账户转账10000.需要执行两条update语句。
update t_act set balance = balance - 10000 where actno = 'act-001';
update t_act set balance = balance + 10000 where actno = 'atc-002';
以上两条DML(数据操纵语言)语句必须同时成功,或者同时失败,不允许出现一条成功,一条失败。如果不同步的话,就会使得数据与操作达不成统一。
要想保证以上两DML语句必须同时成功或者同时失败,那么就需要使用数据库的“事务机制”。
(事务就是用户‘给’数据库操作序列,这些操作要么全做,要么全部做,是一个整体,不可分割)
1.2 和事务相关的语句只有:DML语句。(insert,delete,update)
why? 因为它们这三个语句都是和数据库表当中的数据相关的。
事务的存在是为了保证数据的完整性,安全性。
1.3 假设所有的业务都能使用1条DML语句搞定,还需要事务机制吗?
不需要事务。
但是实际情况不是这样的。通常一个业务需要多条DML语句共同联合完成。
2. 事务的原理
定义事务的语句一般三条:
STAERT TRANSACTION
(mysql事务默认情况下是自动提交的,就是执行任意一条DML语句则提交一次,用 START TRANSACTION; 可以关闭自动提交,然后用commit提交)
COMMIT
ROLLBACK
下面用图阐述一下事务的原理:
3. 事务的特性
3.1事务包括四大特性:ACID
A:原子性(Atomicity):事务是最小的工作单元,不可再分(事务和程序不同,一般地说: 一个程序包含多个事务)
C:一致性(Comsistency):事务必须保证多条DML语句同时成功或者同时失败
I:隔离性(Isolation):事务A与事务B之间具有隔离(也就是各个事务的执行不能相互被打扰)
D:持续性(Durability):持久性说的是最终数据必须持久化到硬盘文件中,事务才算成功。
3. 2关于事务之间的隔离性
事务隔离性存在隔离级别,理论上隔离级别包括四个:
第一级别:读未提交(Read Uncommitted)
对方事务还没有提交,我们当前事务可以读取到对方未提交的数据。
读未提交存在脏读(Dirty Read)现象:表示读到了脏的数据。
第二级别:读已提交(Read Committed)
对方事务提交之后的数据,我方可以读取到。这种级别隔离解决了:脏读现象没有了
读已提交数据存在的问题是:不可重复读。
第三级别:可重复读(Reapeatable Read)
这种隔离级别解决了:不可重复读问题。
这种隔离存在的问题:读取到的数据是幻象
第四级别:序列化读/串行化读(serializable)
解决了所有问题
效率底。需要事务排队。
MySql默认的隔离级别是第三级别(可重复读)。
4. 演示事务
🎈准备表:
drop table if exists t_user;
create table t_user(
id int primary key auto_increment,
username varchar(255)
);
🎈演示:mysql中的事务是支持自动提交的,只要执行一条DML语句,则提交一次
mysql> insert into t_user(username) values('zs');
Query OK, 1 row affected (0.01 sec)mysql> select * from t_user;
+----+----------+
| id | username |
+----+----------+
| 1 | zs |
+----+----------+
1 row in set (0.00 sec)mysql> rollback;
Query OK, 0 rows affected (0.00 sec)mysql> select * from t_user;
+----+----------+
| id | username |
+----+----------+
| 1 | zs |
+----+----------+
1 row in set (0.00 sec)
(发现回滚回不去了,说明mysql事务默认情况下是自动提交的)
🎈演示:使用start transaction关闭自动提交机制
mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)mysql> select * from t_user;
+----+----------+
| id | username |
+----+----------+
| 1 | zs |
+----+----------+
1 row in set (0.00 sec)mysql> insert into t_user(username) values('xiaocai');
Query OK, 1 row affected (0.00 sec)mysql> select * from t_user;
+----+----------+
| id | username |
+----+----------+
| 1 | zs |
| 2 | xiaocai |
+----+----------+
2 rows in set (0.00 sec)mysql> rollback;
Query OK, 0 rows affected (0.00 sec)mysql> select * from t_user;
+----+----------+
| id | username |
+----+----------+
| 1 | zs |
+----+----------+
1 row in set (0.00 sec)
(rollback后事务已经结束,从结果上发现rollback后表数据还原了;如果还想启动一个新事务,应该再次start transaction)
🎈演示 :commit (提交)
mysql> select * from t_user;
+----+----------+
| id | username |
+----+----------+
| 1 | zs |
+----+----------+
1 row in set (0.00 sec)mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)mysql> insert into t_user(username) values('wangwu');
Query OK, 1 row affected (0.00 sec)mysql> insert into t_user(username) values('jack');
Query OK, 1 row affected (0.00 sec)mysql> insert into t_user(username) values('xiaocai');
Query OK, 1 row affected (0.00 sec)mysql> select * from t_user;
+----+----------+
| id | username |
+----+----------+
| 1 | zs |
| 3 | wangwu |
| 4 | jack |
| 5 | xiaocai |
+----+----------+
4 rows in set (0.00 sec)mysql> commit;
Query OK, 0 rows affected (0.01 sec)mysql> rollback;
Query OK, 0 rows affected (0.00 sec)mysql> select * from t_user;
+----+----------+
| id | username |
+----+----------+
| 1 | zs |
| 3 | wangwu |
| 4 | jack |
| 5 | xiaocai |
+----+----------+
4 rows in set (0.00 sec)
(commit后磁盘中的数据就已经改变,如果再rollback回滚只是回滚到前一次提交)
演示隔离级别(利用两个事务)
❗设置事务的全局隔离级别:
set global transaction isolation level read uncommitted;
(这里设置的是第一级别读未提交(read uncommitted)
❗查看事务的全局隔离级别
select @@global.transaction_isolation;
👩💻一、演示read uncommitted
(可以看到一个事务往里面插入元素,还没提交就可以别另一个事务查看了)
👩💻二、演示read committed
(可以看到在一个事务没有提交前另一个事务是查看不到,提交之后就查看到了)
👩💻三、演示repeatable read
(一个事务对该表进行修改了,即使提交了,另一个事务也仍然可以查看原先表数据,也就是查看一个“幻象”,这叫可重复读)
👩💻四、演示serializable
(在一个两个事务共同运行一张表时候,一个事务对表用DML语句进行了数据上的修改,另一个事务要等待修改了的事务提交了才能够操作,相当卡住不动了,上图所示)
(提交之后就另一个事务就可以进行数据操作了)