写点什么

事务特征以及隔离级别

  • 2022 年 5 月 15 日
  • 本文字数:1525 字

    阅读完需:约 5 分钟

事务是如何保证的呢?




这就要说到事务的几个特征:原子性(atomicity)、一致性(consistency)、隔离性(isolation)、持久性(durability),也就是常说的 ACID 特性。


原子性(atomicity):知道原子是什么吗?原子在化学反应中不可分割,也就是说原子是最小单位,一个事务必须被作为一个不可分割的最小工作单员,在一个事务中,所有操作要么同时成功,要么同时不执行,对于同一个事务,永远不能出现一个操作成功,另一个操作失败的情况,这就是事务的原子性。


一致性(consistency):数据库总是从一个一致性的状态转换到另一个一致性的状态,也就是说从一个状态改编成另一个状态,转账为例,初始状态 A 账户 100 元,B 账户 0 元,假设在执行了 A 账户的扣钱操作之后系统奔溃,导致状态的转换没有完成,因此事务不会提交,所以在数据库中数据也不会做出相应的修改。


隔离性(isolation):这个是比较重要的一点,通常来说,一个事务在提交之前的所有操作是对其他事务不可见的,举个例子:A 账户给 B 账户转账 100 元,执行了 1、2 步之后,突然线程被切换了,因为账号这时候账号 B 给账号 A 转 50 元,它查询 A 账户的结果还是 100 元,不会看到被扣除的结果,这就是事务的隔离性。


持久性(durability):这个比较好理解,就是说事务提交之后,事务中所作的所有操作都将永久保存到数据库中,就算系统奔溃,修改的数据也不会丢失。


事务的 ACID 特征保证了转账的准确性,不会导致金钱的丢失,但是,程序中真的要做到不丢失你的金钱是比较复杂的,所以这时候性能可能就不会那么出众了,因为程序、存储引擎会做大量的工作来保证事务的准确性。


就像锁一样,他保证了线程安全,但是降低了可用性,mysql 的存储引擎有很多,有支持事务的也有不支持事务的,比如:InnoDB 支持事务;MyISAM 不支持事务。我们在选型的时候根据项目的需求来判断,对于一些不需要事务的查询类应用,选择 MyISAM 存储引擎可以获得更高的效率,如果个别操作需要事务,也可以通过 lock tables 语句来提供保护。


隔离级别




隔离级别:一个事务必须与由其他事务进行的资源或数据更改相隔离的程度。隔离级别从允许的并发副作用(例如,脏读或虚拟读取)的角度进行描述。


下面我来简单的介绍一下四种隔离级别。


read uncommitted(未提交读):一个事务的修改操作对另外一个事务是可见的,即使事务没有提交;事务可以读取到没有提交事务的修改数据,也就是常说的脏读(Dirty Read),这个隔离级别会让系统产生很 《一线大厂 Java 面试题解析+后端开发学习笔记+最新架构讲解视频+实战项目源码讲义》无偿开源 威信搜索公众号【编程进阶路】 多问题,项目中一般很少使用。


read committed(读提交):一个事务开始只能看到已经提交事务所作的修改操作,也就是说在事务未提交之前所修改的数据对另一个事务不可见,也就不可重复读,执行两次相同的查询,结果可能会不相同,这是大多数数据库的默认隔离级别(mysql 除外)。


repeatable read(可重复读):该级别保证了同一个事物中多次读取相同数据的结果是一致的,但是可重复读还是不能解决另外一个问题,那就是:幻读(Phantom Read),幻读指的是:当某个事物读取某个范围内的记录时,被另外一个事务在该范围内新增了一条记录,当前事务再次读取该范围的记录时,会产生幻行(Phantom Row),InnoDB 和 XtraBDB 存储引擎通过多版本并发控制解决了幻读问题,这种隔离级别时 mysql 的默认隔离级别。


serializable(可串行化):顾名思义,它要求所有的事务都串行化执行,这避免了可重复读的幻读问题,他是怎么让事务串行化的呢?这是因为 serializable 会在读取的数据上加锁,保证串行化,但是这就会导致有大量的 sql 超时和锁竞争的问题。这种隔离级别在项目中也是不常用的,除了特殊情况。


最后,在给出一个各个隔离级别的数据对比:

用户头像

还未添加个人签名 2022.04.13 加入

还未添加个人简介

评论

发布
暂无评论
事务特征以及隔离级别_Java_爱好编程进阶_InfoQ写作社区