mysql事务

2021/6/2 19:24:05

本文主要是介绍mysql事务,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

mysql事务四大特性
1.原子性
理解:事务中的所有操作要么全部一起执行,要么在发生的错误的时候全部不执行,也就是事务回滚了
原理:mysql使用undo log逻辑日志进行回滚,mysql会生成redo log和undo log 文件,undo log文件在数据库进行回滚时,会做之前相反的操作,比如回滚前是新增,那么根据undo log就是删除,回滚前是删除,那么根据undo log就是新增
2.持久性
理解:mysq通过redo log文件在系统空闲时间或按预先设定的更新策略将日志文件中的数据更新至磁盘,这就是预写式技术,这种技术可以大大减少IO操作的频率,提升数据刷新的效率。
3.隔离性
理解:同一时间里,只允许一个事务去请求同一数据,其它事务不能操作这一数据,事务与事务之间没有任何的干扰,例如:a向银行卡取钱,a在取钱的过程还没结束时,b不能向这个银行卡转账。
原理:mysql数据库通过锁、以及锁的粒度如:行级锁、表级锁、页级锁

事务之间的隔离,是通过锁机制实现的。当一个事务需要对数据库中的某行数据进行修改时,需要先给数据加锁。加了锁的数据,其它事务是不运行操作的,只能等待当前事务提交或回滚将锁释放。锁机制并不是一个陌生的概念,在许多场景中都会利用到不同实现的锁对数据进行保护和同步。而在MySQL中,根据不同的划分标准,还可将锁分为不同的种类。

按照粒度划分:行锁、表锁、页锁
按照使用方式划分:共享锁、排他锁
按照思想划分:悲观锁、乐观锁
接下来按上面的顺序介绍下这些锁的类别和特点:

粒度(行锁、表锁、页锁)
从锁的粒度这个方面来看,表锁在操作数据时会锁定整张表,因而并发性能较差。行锁则只锁定需要操作的数据,并发性能好,但是由于加锁本身需要消耗资源(获得锁、检查锁、释放锁等都需要消耗资源),因此在锁定数据较多情况下使用表锁可以节省大量资源。页锁是粒度介于行级锁和表级锁中间的一种锁,表示对页进行加锁。

MySQL中不同的存储引擎能够支持的锁也是不一样的。MyISAM只支持表锁,而InnoDB同时支持表锁和行锁,且出于性能考虑,绝大多数情况下使用的都是行锁。

InnoDB 行锁是通过给索引项加锁实现的,如果没有索引,InnoDB会通过隐藏的聚簇索引来对记录加锁。也就是说,如果不通过索引条件检索数据,那么InnoDB将对表中所有数据加锁,实际效果跟表锁一样。因为没有了索引,找到某一条记录就得扫描全表,要扫描全表,就得锁定表。

使用方式(共享锁、排他锁)
共享锁又称为读锁,简称S锁,顾名思义,共享锁就是多个事务对于同一数据可以共享一把锁,都能访问到数据,但是只能读不能修改。

排他锁又称为写锁,简称X锁,顾名思义,排他锁就是不能与其他所并存,如一个事务获取了一个数据行的排他锁,其他事务就不能再获取该行的其他锁,包括共享锁和排他锁。获取排他锁的事务是可以对数据就行读取和修改。

注意:对于select语句,InnoDB不会加任何锁,也就是可以多个并发去进行select的操作,不会有任何的锁冲突,因为根本没有锁。对于insert,update,delete操作,InnoDB会自动给涉及到的数据加排他锁,只有查询select需要我们手动设置排他锁。

思想(悲观锁、乐观锁)
悲观锁(Pessimistic Concurrency Control),正如其名,它指的是对数据被外界(包括本系统当前的其他事务,以及来自外部系统的事务处理)修改持保守态度,因此,在整个数据处理过程中,将数据处于锁定状态。 悲观锁的实现,往往依靠数据库提供的锁机制 (也只有数据库层提供的锁机制才能真正保证数据访问的排他性,否则,即使在本系统中实现了加锁机制,也无法保证外部系统不会修改数据)。悲观锁通过常用的select … for update操作来实现悲观锁,悲观锁的流程也被称为:一锁二查三更新。

悲观并发控制实际上是“先取锁再访问”的保守策略,为数据处理的安全提供了保证。但是在效率方面,处理加锁的机制会让数据库产生额外的开销,还有增加产生死锁的机会。另外,在只读型事务处理中由于不会产生冲突,也没必要使用锁,这样做只能增加系统负载。还有会降低了并行性,一个事务如果锁定了某行数据,其他事务就必须等待该事务处理完才可以处理那行数据。

乐观锁( Optimistic Locking ) 相对悲观锁而言,乐观锁假设认为数据一般情况下不会造成冲突,所以在数据进行提交更新的时候,才会正式对数据的冲突与否进行检测,如果发现冲突了,则让返回用户错误的信息,让用户决定如何去做。乐观锁通常使用版本标识方法来实现,比如MVCC。

乐观并发控制相信事务之间的数据竞争(data race)的概率是比较小的,因此尽可能直接做下去,直到提交的时候才去锁定,所以不会产生任何锁和死锁。但如果这么做,还是有可能会遇到不可预期的结果,例如两个事务都读取了数据库的某一行,经过修改以后写回数据库,这时就遇到了问题。

一致性
一致性是指事务执行结束后,数据库的完整性约束没有被破坏,事务执行的前后都是合法的数据状态。一致性是事务追求的最终目标,原子性、持久性和隔离性,实际上都是为了保证数据库状态的一致性而存在的。

换句话说,ACID里的AID都是数据库的特征,也就是依赖数据库的具体实现。而唯独这个C,实际上它依赖于应用层,也就是依赖于开发者。这里的一致性是指系统从一个正确的状态,迁移到另一个正确的状态。什么叫正确的状态呢?就是当前的状态满足预定的约束就叫做正确的状态。而事务具备ACID里C的特性是说通过事务的AID来保证我们的一致性。



这篇关于mysql事务的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程