【MySQL】事务

目录

1. 事务(Transaction)的概述

1.1 什么是事务

1.2 和事务相关的语句只有:DML语句。(insert,delete,update)

1.3 假设所有的业务都能使用1条DML语句搞定,还需要事务机制吗?

2. 事务的原理

 3. 事务的特性

3.1事务包括四大特性:ACID

3. 2关于事务之间的隔离性

4. 演示事务

🎈演示:mysql中的事务是支持自动提交的,只要执行一条DML语句,则提交一次

🎈演示:使用start transaction关闭自动提交机制

🎈演示 :commit (提交)

演示隔离级别(利用两个事务)

❗设置事务的全局隔离级别:

👩‍💻一、演示read uncommitted

👩‍💻二、演示read committed

👩‍💻三、演示repeatable read

👩‍💻四、演示serializable


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语句进行了数据上的修改,另一个事务要等待修改了的事务提交了才能够操作,相当卡住不动了,上图所示)

(提交之后就另一个事务就可以进行数据操作了)

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

假正经的小柴

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值