文章目录
✍事务是什么?
事务是由一个或多个SQL语句构成的,在事务中,这些的SQL不可分割,是一个整体,整个事务类似于物理中的原子结构,不可再分。
简单概括,就是说,将多个语句给打包成一个整体了,在这个整体中的语句,要么一条都不执行,要么全部执行,不存在部分执行或者部分不执行的情况。
这样的定义,有效的避免了部分执行,部分未执行而产生的一些“中间状态·”引起的问题
举例来说:在转账系统中,支付者支付金钱和接收者接收金钱就是一个“事务”,他们两者只会同时执行或同时不执行,不会存在支付者支付金钱后,接收者没有接收到金钱这样的情况。
注意:全部不执行
这里的全部不执行,并非字面的一个语句都不执行,在进行操作时,SQL语句会一条一条的执行,当数据库遇到一些特殊情况时(例如:程序崩溃,主机断电,系统崩溃,网络断开…),数据库会将先前执行的SQL语句给一句一句恢复回去,这里的操作叫做“回滚”,使程序恢复如初,看起来就好像是一句都没有执行
回滚
为什么能实现回滚操作呢?是因为数据库在事务时,会记录日志(写入到硬盘)当事务执行完后,并没有差错,就会删除掉。
如果过程中出现了问题,就会根据日志来进行处理
- 之前进行过新增操作,就会把数据删除
- 之前进行过更改数据,就会恢复数据
- 之前进行过删除操作,就会新增删除的数据
- 之前进行过查询操作,没有影响,不会做出操作
✍事务的特性(四个)
- 原子性 :指事务不可再分的最小单位。事务中的操作只有全部发生和全部不发生这两种情况。
- 一致性:指事务执行之前和执行之后,数据是一致的。 例如转账时,A转给B,500元,那么A的账户就会少500,B的账户就会多500.
- 持久性:执行事务对数据的修改存放于硬盘上,会在硬盘上持久存在,下次程序重启,机器重启对数据的修改还是存在的。
- 隔离性:一个事务的执行不能被其他事务干扰,即一个事务内部的操作及使用的数据对并发的其他事务是隔离的,并发执行的各个事务之间不能互相干扰。 会”加锁“,防止脏读情况的发生,从而提高了并发处理的准确性。 “写加锁”,写的时候,不能读取数据。
✍事务并发时出现的问题
1.脏读
当事务A在对数据进行修改时,事务A等待一段时间,此时在等待过程中,事务B记录下了A对数据修改的结果,等待时间过后,事务A继续修改,此时事务B误将这次的结果作为最终结果记录下来。
这就是脏读。
2.不可重复读
存在三个事务ABC。
事务A对数据进行修改,接下来事务B进行读取数据(事务B的多个SQL都要进行读操作),在执B的过程中,又有一个事务C对数据进行了修改。
就会使B里面的不同读操作,读出来的结果不一样。
所以再进一步规定。进一步加锁–读加锁
3.幻读
事务A先修改并提交数据。事务B进行读取数据。此时事务C没有修改事务B读取的数据,但是给对应的表进行了新增数据/删除数据等操作…导致事务B读到的数据集不同(已有的数据是一致的,只是数据的条数增加/减少),可以视为是“不可重复读”的特殊情况。
解决幻读:
所以的事务,“串行化”使事务严格按照一个接一个进行执行,此时完全没有并发了,执行的效率最低,同时事务的隔离性最高。
总结:
- 脏读–写加锁
- 不可重复读–读加锁
- 幻读–串行化
在解决实际问题中,要想要保证数据的准确性,就需要牺牲一些效率。具体跟业务场景所定。
✍事务的隔离性
MySQL提供了四个隔离级别。
- read uncommitted:允许读取其他事务未提交的数据 --> 存在: 脏读+不可重复读+幻读 。 并发程度最高,隔离性最低.
- read committed:只能读取其他事务提交后的数据 --> 解决了脏读,存在不可重复读,幻读。 并发程度降低,隔离性提高。
- repeatable read:针对读操作和写操作都加了锁 --> 解决了脏读+不可重复读,存在幻读。 并发程度又降低,隔离性又提高。
- 串行化(serializable):所有的事务都是串行执行的–> 解决了脏读+不可重复读+幻读。 并发基本没有,隔离性最高
以上就是本文所有内容,如果对你有帮助的话,点赞收藏支持一下吧!💞💞💞
版权归原作者 爱吃南瓜的北瓜 所有, 如有侵权,请联系我们删除。