MySQL事务(脏读,幻读,不可重复读)

什么是MySQL事务?

事务(Transaction),就是将一组SQL语句放在同一批次内去执行,如果一个SQL语句出错,则该批次内 的所有SQL都将被取消执行。

事务的提交与回滚:

例子:如果你给别人转账,按照数据库来看分几步?

1.修改你的账户余额数

2.修改转账对象的账户余额数

-- 创建一个银行表
create table bank(
	bid int primary key auto_increment,
	bname varchar(10),
	bmoney decimal(20,2)
);

-- 增添两条数据
-- 马普 有10000000000000000钱
-- 柳玺 有5块

insert into bank(bname,bmoney) 
values('马普',10000000000000000),('柳玺',5);

-- 转账也就是修改其中数据,马普给柳玺转账1000元

update bank set bmoney=bmoney-1000 where bname='马普';
update bank set bmoney=bmoney+1000 where bname='柳玺';

select * from bank;

转账前

 转账后

 

那么问题来了,如果中间发生了转账错误,钱的数据丢失在了1-2之间,怎么办?

我们首先想到的就是回退操作,将一切还原到未发生前的状态。这就是事务的回滚。如果操作完是你满意的结果,那么你的做一个确认的操作,这就是事务的提交。

事务的操作流程:

1.关闭事务自动提交

        我们对数据库进行普通的操作时,从来没有写过事务的提交回滚,是因为数据库事务的提交时默认开启的,所以在进行事物的操作时,我们应该先讲事务自动提交关闭,由我们人为来控制事务到底该不该提交。

        语句:SET AUTOCOMMIT = 0;

2.开启事务

        语句:START TRANSACTION;

3.执行一组你要进行的sql语句

4.1如果,确定你执行完的结果是你所要的,提交事务

        语句:COMMIT;

4.2如果,执行完的结果不是我们所要的结果,要进行事务的回滚

        语句:ROLLBACK;

5.开启事务的自动提交

        语句:SET AUTOCOMMIT = 1;

-- 事务的操作
-- 1. 关闭自动提交
set autocommit = 0;

-- 2. 开启事务
start transaction;

-- 3. 执行一组sql语句
update bank set bmoney=bmoney-1000 where bname='马普';
update bank set bmoney=bmoney+1000 where bname='柳玺';

-- 4. 结束事务
-- 4.1 提交
commit;
-- 4.2 回滚
rollback;

set autocommit = 1;

事务的四大原则:

原子性:

        意味着数据库中的 事务执行是作为原 子粒度。即不可再分,整个语句要么执行,要么不执行

一致性:

        即在事务开始之前和 事务结束以后,数据库的完整性约束没有被破坏。

隔离性:

        事务的执行是互不干扰的,一个事务不可能看到其他事务运行时,中间某 一时刻的数据。

一致性:

        意味着在事务完成以后 ,该事务所对数据库所作的更改便持久的保存在数据库之中,并不会 被回滚。

事务隔离性的等级:

        查看事务的隔离等级:

        语句:select @@global.transaction_isolation,@@transaction_isolation;

 事务的隔离等级有四点,每种隔离等级有其会出现的情况

1.Read Uncommitted(读取未提交内容)

        在该隔离级别,所有事务都可以看到其他未提交事务的执行结果。本隔离级别很少用于实际应用,因为它的性能也不比其他级别好多少。读取未提交的数据,也被称之为脏读(Dirty Read)。

2.Read Committed(读取提交内容 也叫做不可重复读

        这是大多数数据库系统的默认隔离级别(但不是MySQL默认的)。它满足了隔离的简单定义:一个事务只能看见已经提交事务所做的改变。这种隔离级别 也支持所谓的不可重复读(Nonrepeatable Read),因为同一事务的其他实例在该实例处理其间可能会有新的commit,所以同一select可能返回不同结果。

 一个事务读某条数据读两遍,读到的是不一样的数据,也就是说,一个事务在进行中读取到了其他事务对旧数据的修改结果,(比如说 我开一个事务 修改某条数据 先查后改 执行修改动作的时候发现这条数据已经被别的事务删掉了)

3.Repeatable Read(可重读)

       这是MySQL的默认事务隔离级别,它确保同一事务的多个实例在并发读取数据时,会看到同样的数据行。不过理论上,这会导致另一个棘手的问题:幻读 (Phantom Read)。简单的说,幻读指当用户读取某一范围的数据行时,另一个事务又在该范围内插入了新行,当用户再读取该范围的数据行时,会发现有新的“幻影” 行。InnoDB和Falcon存储引擎通过多版本并发控制(MVCC,Multiversion Concurrency Control)机制解决了该问题。

一个事务中,读取到了其他事务新增的数据,仿佛出现了幻象。(幻读与不可重复读类似,不可重复读是读到了其他事务update/delete的结果,幻读是读到了其他事务insert的结果)

 4.Serializable(可串行化)

        这是最高的隔离级别,它通过强制事务排序,使之不可能相互冲突,从而解决幻读问题。简言之,它是在每个读的数据行上加上共享锁。在这个级别,可能导致大量的超时现象和锁竞争。

会出现的问题:

1.脏读(Drity Read):

        某个事务已更新一份数据,另一个事务在此时读取了同一份数据,由于某些原因,前一个RollBack了操作,则后一个事务所读取的数据就会是不正确的。

2.不可重复读(Non-repeatable read):

        在一个事务的两次查询之中数据不一致,这可能是两次查询过程中间插入了一个事务更新的原有的数据。

3.幻读(Phantom Read):

        在一个事务的两次查询中数据笔数不一致,例如有一个事务查询了几列(Row)数据,而另一个事务却在此时插入了新的几列数据,先前的事务在接下来的查询中,就会发现有几列数据是它先前所没有的。

 

看完有用留赞好习惯

 

  • 5
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
脏读是指一个事务可以读取到另一个事务未提交的数据。不可重复读是指在一个事务内多次读取同一数据时,由于其他事务的修改导致每次读取的结果不一致。幻读是指在一个事务内多次执行相同的查询,由于其他事务的插入或删除导致每次查询的结果不一致。 在MySQL中,事务隔离级别对应的脏读不可重复读幻读的情况如下: - 读未提交(READ UNCOMMITTED)级别下存在脏读不可重复读幻读的问题。 - 读已提交(READ COMMITTED)级别下不存在脏读的问题,但仍可能存在不可重复读幻读的问题。 - 可重复读(REPEATABLE READ)级别下不存在脏读不可重复读的问题,但仍可能存在幻读的问题。 - 串行化(SERIALIZABLE)级别下不存在脏读不可重复读幻读的问题。 因此,在MySQL中,脏读不可重复读幻读都是与事务隔离级别密切相关的读一致性问题。根据需求和业务场景,可以选择合适的事务隔离级别来解决这些问题。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [Mysql-详解脏读不可重复读幻读](https://blog.csdn.net/ahuangqingfeng/article/details/124407846)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* *3* [一文搞懂MySQL脏读,幻读不可重复读](https://blog.csdn.net/liuqinhou/article/details/126360614)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值