数据库事务的四个主要特征(ACID)和事务的隔离级别
什么是数据库的事务?事务其实就是单个数据逻辑单元组成的对象操作集合,而数据库的终极目标就是使数据库从一个一致的状态转换到另一个一致的状态,这就是ACID中的一致性(Consistency),而原子性(Atomicity)、隔离性(Isolation)、持久性(Durability)是为了实现这个目标的手段。
一个事务是一连串的操作组成,增删改查的集合。就好比java方法一样,java方法中有N条语句对属性进行修改。在java执行语句中,有一个语句执行出现问题而导致抛出异常了,那么相当于这个方法只执行了一半。如果只执行了一半,那么它的一致性很有可能遭到了破坏。所以原子性就要求你一个java方法要么你就全部执行成功,要么你就不执行,我不允许你只执行一半。所以原子性是一致性的必要条件,但是只要保证了原子性就可以保证一致性了吗?显然不是,所以原子性是一致性的一个必要条件,但是不充分条件。
好的,这时候我们假设原子性保证了。一个事务未提交的时候,发生了错误就执行rollback,那么事务就不会提交了。但是当我们事务执行成功了,执行commit指令之后,遇到了错误会怎么样?我们都知道,执行commit后会让事务刷盘,进行持久化操作。进行刷盘操作时是需要一定时间的,在这个刷盘过程中出现宕机、停电、系统崩溃等等可以中断刷盘的操作,那么这个过程会不会有一半数据刷盘成功,另一半没有刷进去?当然不会出现,持久性就保证了,但你当你提交事务commit之后,它一定会持久化到数据库中。尽管你写了一半的数据到数据库中,然后数据库宕机了,当你下一次重启的时候,数据库根据提交日志进行回滚,将另一半的数据写入,至于是如何操作的,这是一个非常复杂而艰难的过程,伟大的oracle程序员已经为我们做好了,我们就不用操心了。
原子性,持久性他们两个都是事务一致性的充分条件,但是还无法构成必要条件。这两个都解决了,接下来就是线程安全的问题了。数据库是支持并发访问,这是毫无疑问的。隔离性,官方解释是说“在并发事务下,多个事务有自己的事务空间,相互独立互不干扰。我们在一个事务中是感觉不到其他并发事务的存在”。以java方法来说的话,不同的方法都有自己的栈帧,虽然多个线程调用同一个方法,但是不同进程,进入这个方法的栈帧是相互独立的。如果你在这个类中定义了成员变量,线程在工作时,会将主内存中的数据拷贝到工作内存的栈帧中。这样对数据的任何操作都是基于工作内存(效率提高),并且不能直接操作主内存以及其他线程工作内存中的数据,之后再将更新之后的数据刷新到主内存中。这种肯定会引起线程安全问题,解决线程安全问题,通常来说就是加锁,java为我们提供了不同锁粒度的锁,来供我们用户自己选择。我们可以再变量上加入volitate来实现内存可见性,还可以加入synchronized实现同步方法块。
回到隔离性,很显然事务的隔离性,说的就是,多个并发事务实际上都是独立事务上下文,多个事务上下文之间彼此隔离,互补干扰。但是多个事务如果对共享数据进行查看,删除,修改如果不加以修改,就会出现线程安全问题。如何避免,你可能会使用一把锁,当线程A修改共享数据的时候,让线程B不要来查看共享数据,除非等我修改完毕;或者说,我不让别人读取到我修改共享数据的中间值,只能读取到初始值,和我修改完成之后的值。但是这些都是你根据业务来操作的,所以数据库为我们封装了‘四把锁’,对应四种隔离级别:
- 读未提交,其隔离级别最低,允许脏读。换句话说就是,如果一个事务正在处理某一数据,并对其进行了更新,但是同时没有提交事务,允许另一个事务也可以访问
- 读已提交,和读未提交的区别就是。读未提交可以读取到别人没有提交的数据,但是读已提交只能读取到别人提交后的值,事务进行的中间值不会读取到
- 可重复读,简单来说就是事务处理过程中多次读取同一个数据的时候,这个值不会发生改变,其值都和第一次查询到的数据是一致的
- 可串行化,是最严格的隔离级别,他要求所有的事务都被串行执行,既事务只能一个接一个的进行处理,不能并发执行
隔离性远比上面介绍的这样简单,更详细的内容请查看我另一篇博客:细说数据库隔离级别
这样原子性、持久性、隔离性(锁机制以及各种并发安全控制机制)和事务一致性就构成了充分必要条件
最后,如果感觉对你有帮助就来个二连吧:关注、点赞!
上一篇: 交易的四大特点及实施原则
下一篇: 数据库事务和事务隔离级别的四个主要特征
推荐阅读
-
什么是事务?事务的四个特征(ACID)?并发事务会带来哪些问题?什么是事务隔离级别?事务的传播特性
-
什么是数据库事物?为什么需要数据库事物,事物有哪些特征?事物的隔离级别是什么?-1.什么是数据库事务? 1.事务是作为一个逻辑单元执行的一系列操作。一个逻辑工作单元必须具备四个属性,即ACID(原子性、一致性、隔离性和持久性)属性,只有这样才能成为事务: 原子性 2.事务必须是一个原子工作单元;它的数据修改要么全部执行,要么全部不执行。 一致性 3.事务完成时,所有数据必须保持一致。在相关数据库中,所有规则都必须适用于事务的修改,以保持所有数据的完整性。事务结束时,所有内部数据结构(如 B 树索引或双向链接表)必须正确无误。 隔离 4.并发事务的修改必须与其他并发事务的修改隔离。一个事务会在另一个并发事务修改之前或之后查看某一状态下的数据,而不会查看中间状态下的数据。这就是所谓的可序列化,因为它允许重新加载起始数据和重放一系列事务,从而使数据最终处于与原始事务执行时相同的状态。 持久性 5.事务完成后,它对系统的影响是永久性的。即使在系统发生故障的情况下,修改也会保留。 2. 为什么需要数据库事物,事物有哪些特征? 事物对数据库的作用是对数据进行一系列操作,要么全部成功,要么全部失败,防止出现中间状态,确保数据库中的数据始终处于正确、和谐的状态。 特征:原子性、一致性、隔离性、持久性,以及其他特征 原子性(Atomicity):所有操作在事务开始后,要么全部做完,要么全部不做,不可能停滞在中间环节。事务执行过程中出现错误时,会回滚到事务开始前的状态,所有操作就像没有发生一样。也就是说,事务是一个不可分割的整体,就像化学中的原子一样,是物质的基本单位。 一致性(Consistency):在事务开始之前和结束之后,数据库的完整性约束都没有被破坏。例如,如果 A 转钱给 B,A 不可能扣除这笔钱,但 B 却没有收到这笔钱。 隔离:在同一时间内,只允许一个事务请求相同的数据,不同事务之间没有干扰。例如,甲正在从一张银行卡上取款,在甲取款过程结束之前,乙不能向这张卡转账。 持久性(耐用性):事务完成后,事务对数据库的所有更新都将保存到数据库中,无法回滚 3.事务的隔离级别有哪些? 数据库事务有四种隔离级别,从低到高分别是未提交读取(Read uncommitted)、已提交读取(Read committed)、可重复读取(Repeatable read)、可序列化(Serializable)。此外,事务的并发操作中可能会出现脏读、不可重复读、幽灵读等情况。事务并发问题 脏读:事务 A 读取事务 B 更新的数据,然后事务 B 回滚操作,那么事务 A 读取的数据就是脏数据。 不可重复读取:事务 A 多次读取同一数据,事务 B 在事务 A 多次读取期间更新并提交数据,导致事务 A 多次读取同一数据时结果不一致。 幻影读取:系统管理员 A 将数据库中所有学生的具体分数改为 ABCDE 等级,但系统管理员 B 在此时插入了具体分数的记录,当系统管理员 A 更改结束后发现仍有一条记录未被更改,仿佛发生了幻觉,这称为幻影读取。 小结:不可重复读和幻读容易混淆,不可重复读侧重于修改,幻读侧重于增删。解决不可重复读问题只需锁定满足条件的行,解决幻读问题则需要锁定表 MySQL 事务隔离级别
-
数据库事务和事务隔离级别的四个主要特征
-
数据库事务和事务隔离级别的四个主要特征
-
数据库事务的四个主要特征(ACID)和事务的隔离级别
-
关于事务的四个特征、事务的隔离级别、事务的并发性
-
了解事务(Transaction)的四个特性--原子性、一致性、隔离性和持久性(ACID)
-
数据库事务的四个主要特征和隔离级别
-
透彻解读 MySQL 事务的四个隔离级别
-
数据库事务和事务隔离级别的四个主要特征