MySQL事务相关知识

 实践阅读:一文彻底读懂MySQL事务的四大隔离级别

1、什么是事务?

        数据库事务(简称:事务),是数据库管理系统执行过程中的一个逻辑单位,由一个有限的数据库操作序列构成,这些操作要么全部执行,要么全部不执行,是一个不可分割的工作单位。

假如A转账给B 100 元,先从A的账户里扣除 100 元,再在 B 的账户上加上 100 元。如果扣完A的100元后,还没来得及给B加上,银行系统异常了,最后导致A的余额减少了,B的余额却没有增加。所以就需要事务,将A的钱回滚回去,就是这么简单。 

2、MySQL事务的四大特性以及实现原理?

事务特性ACID原子性Atomicity)、一致性Consistency)、隔离性Isolation)、持久性Durability)。 

  • 原子性(Atomicity): 事务作为一个整体被执行,包含在其中的对数据库的操作要么全部都执行,要么都不执行,是一个不可分割的整体。
  • 一致性(Consistency): 指在事务开始之前和事务结束以后,数据不会被破坏,假如A账户给B账户转10块钱,不管成功与否,A和B的总金额是不变的。
  • 隔离性(Isolation): 多个事务并发访问时,事务之间是相互隔离的,一个事务不应该被其他事务干扰,多个并发事务之间要相互隔离。
  • 持久性(Durabilily): 表示事务完成提交后,该事务对数据库所作的操作更改,将持久地保存在数据库之中。

事务ACID特性的实现思想:

原子性:是使用 undo log来实现的,如果事务执行过程中出错或者用户执行了rollback,系统通过undo log日志返回事务开始的状态。

持久性:使用 redo log来实现,只要redo log日志持久化了,当系统崩溃,即可通过redo log把数据恢复。

隔离性:通过锁以及MVCC,使事务相互隔离开。

一致性:通过回滚、恢复,以及并发情况下的隔离性,从而实现一致性。

3、事务并发会存在哪三种问题?

事务并发会引起数据的脏读、不可重复、幻读等问题。 

脏读(dirty read) 是指在一个事务处理过程里读取了另一个未提交的事务中的数据。

  • 假设现在A的余额是100,事务A正在准备查询Jay的余额
  • 这时候,事务B先扣减Jay的余额,扣了10
  • 最后A 读到的是扣减后的余额
  • 事务A、B交替执行,事务A被事务B干扰到了,因为事务A读取到事务B未提交的数据,这就是脏读


不可重复读(unrepeatable read) 是指在对于数据库中的某行记录,一个事务范围内多次查询却返回了不同的数据值,这是由于在查询间隔,另一个事务修改了数据并提交了。

  • 事务A先查询Jay的余额,查到结果是100
  • 这时候事务B 对Jay的账户余额进行扣减,扣去10后,提交事务
  • 事务A再去查询Jay的账户余额发现变成了90
  • 事务A又被事务B干扰到了!在事务A范围内,两个相同的查询,读取同一条记录,却返回了不同的数据,这就是不可重复读


幻读  是当某个事务在读取某个范围内的记录时,另外一个事务又在该范围内插入了新的记录,当之前的事务再次读取该范围的记录时,会产生幻行,就像产生幻觉一样,这就是发生了幻读。

  • 事务A先查询id大于2的账户记录,得到记录id=2和id=3的两条记录
  • 这时候,事务B开启,插入一条id=4的记录,并且提交了
  • 事务A再去执行相同的查询,却得到了id=2,3,4的3条记录了。
  • 事务A查询一个范围的结果集,另一个并发事务B往这个范围中插入/删除了数据,并静悄悄地提交,然后事务A再次查询相同的范围,两次读取得到的结果集不一样了,这就是幻读

不可重复读侧重于修改,幻读侧重于新增或删除(多了或少量行),脏读是一个事务回滚影响另外一个事务。 

4、事务的四大隔离级别是什么?

        事务隔离就是为了解决上面提到的脏读、不可重复、幻读等问题,MySQL实现了四种类型的隔离级别:

  • 读未提交(Read Uncommitted)在本隔离级别,所有事务都可以看到其他未提交事务的执行结果。 本隔离级别很少用于实际应用,因为它的性能也不比其他级别好多少。读取未提交的数据,也被称之为脏读(Dirty Read)。
  • 读已提交(Read Committed)一个事务只能看见已经提交事务所做的改变。可避免脏读的发生
  • 可重复读(Repeatable Read)MySQL的默认事务隔离级别,它确保同一事务的多个实例在并发读取数据时,会看到同样的数据行,解决了不可重复读的问题。不过理论上,这会导致另一个棘手的问题:幻读 (Phantom Read)。
  • 串行化(Serializable)通过强制事务排序,使之不可能相互冲突,从而解决幻读问题。简言之,它是在每个读的数据行上加上共享锁。在这个级别,可能导致大量的超时现象和锁竞争。

5、如何查看和设置事务的隔离级别?

-- 查看当前事务的隔离级别
SELECT @@transaction_isolation;
-- 或者简写
select @@tx_isolation

-- 查询可得到当前默认的事务隔离级别为 REPEATABLE-READ(可重复读)
mysql> SELECT @@transaction_isolation;
+-------------------------+
| @@transaction_isolation |
+-------------------------+
| REPEATABLE-READ         |
+-------------------------+
1 row in set (0.00 sec)

-- 设置隔离级别
set session transaction isolation level read uncommitted;  -- 设置为读未提交
set session transaction isolation level read committed;  -- 设置为读已提交
set session transaction isolation level repeatable read;  -- 设置为可重复读(默认的)
set session transaction isolation level serializable;   --设置为串行化

6、如何设置事务的手动commit提交

-- 查看当前事务的提交状态
mysql> show variables like '%commit%';
+-----------------------------------------+-------+
| Variable_name                           | Value |
+-----------------------------------------+-------+
| autocommit                              | ON    |   -- 默认是开启状态
| binlog_group_commit_sync_delay          | 0     |
| binlog_group_commit_sync_no_delay_count | 0     |
| binlog_order_commits                    | ON    |
| innodb_api_bk_commit_interval           | 5     |
| innodb_commit_concurrency               | 0     |
| innodb_flush_log_at_trx_commit          | 1     |
| replication_sender_observe_commit_only  | OFF   |
| slave_preserve_commit_order             | OFF   |
+-----------------------------------------+-------+

-- 关闭事务自动提交
SET autocommit = 0;   -- 0 关闭 1 开启
或者:
SET autocommit = off   -- off 或 on

-- 默认情况下 autocommit = 1,是自动提交事务的。
-- autommit 是 session 级别的,就是当前连接更改了autocommit对其他连接没有影响。
-- 设置 autocommit 之后,本次连接的所有 sql 都是事务的形式,比如每次 commit 提交。

 7、开启事务、提交事务、事务回滚的命令是什么?

-- 演示的时候首先设置 SET autocommit = 0; 把提交事务设置为手动提交
-- 开启事务
mysql> begin;
或者:
mysql> start transaction;

-- 提交事务
mysql> commit;

-- 事务回滚
mysql> rollback;

8、MySql隔离级别的实现原理

实现隔离机制的方法主要有两种:

  • 读写锁
  • 一致性快照读,即 MVCC

MySql使用不同的锁策略(Locking Strategy)/MVCC来实现四种不同的隔离级别。RR、RC的实现原理跟MVCC有关,RU和Serializable跟锁有关。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值