1、事务定义
事务(TRANSACTION)是作为单个逻辑工作单元执行的一系列操作,这些操作作为一个整体一起向系统提交,要么都执行、要么都不执行 。事务是一个不可分割的工作逻辑单元事务必须具备以下四个属性,简称 ACID 属性:
原子性(Atomicity):事务是一个完整的操作。事务的各步操作是不可分的(原子的);要么都执行,要么都不执行。(undo log 实现)
一致性(Consistency):当事务完成时,数据必须处于一致状态。
隔离性(Isolation):对数据进行修改的所有并发事务是彼此隔离的,这表明事务必须是独立的,它不应以任何方式依赖于或影响其他事务。(由锁机制和MVCC机制来实现)。
永久性(Durability):事务完成后,它对数据库的修改被永久保持,事务日志能够保持事务的永久性。(redo log 实现)
1.1、事务的原子性是如何保证的?
实现原子性的关键,是当事务回滚时能够撤销所有已经成功执行的sql语句。InnoDB实现回滚,靠的是undo log:当事务对数据库进行修改时,InnoDB会生成对应的undo log;如果事务执行失败或调用了rollback,导致事务需要回滚,便可以利用undo log中的信息将数据回滚到修改之前的样子。
undo log还要另外一个重要作用,就是用于mvcc中,进行多版本控制,也就是实现事务隔离性的基础,当用户读取一行记录时,如果这个记录已接被其他事务占用,那么当前事务就可以通过undo读取之前的行版本信息,用来实现非锁定读取,就是“快照读”。
1.2、事务的持久性是如何实现的?
redo log实现事务的持久性。
1.3、事务的隔离性是如何实现的?
事务的隔离性通过 锁 和 MVCC 来解决。 锁 解决了 写-写操作之间的并发隔离,MVCC 解决了 写-读操作之间的并发隔离。
1.3.1、行锁
InnoDB中,实现了两种标准的行级锁:
普通select语句不会有任何锁,那么如何获得共享锁和排它锁呢?
当一个事务A已经获得了行r的共享锁,那么另一个事务B可以立刻获得行r的共享锁,因为不会改变r的数值,这种叫做锁兼容。
如果这时候有事务C希望获得行r的排它锁,那么就必须等待事务A和事务B释放行r的共享锁之后,才能获得排它锁,这种叫做锁不兼容。
普通的select不会对行上锁,而select…lock in share mode会上共享锁,select…for update会上排它锁。
如果在update、insert的时候,不能进行select,那么服务的并发访问性能就太差了。因此,我们日常的查询,都是“快照读”,不会上锁,只有在update\insert\“当前读”的时候,才会上锁。而为了解决“快照读”的并发访问问题,就引入了MVCC。
1.3.2、MVCC
MVCC即多版本并发控制,所谓多版本是指一行记录在数据库中存储了多个版本,每个版本以事务ID作为版本号。在每个记录多版本的基础上,需要利用“一致性视图”来做版本的可见性判断。
一致性视图定义了在事务期间,能看到那些版本的数据。
1.4、事务的一致性是如何实现的?
从数据库层面,数据库通过原子性、隔离性、持久性来保证一致性。也就是说ACID四大特性之中,C(一致性)是目的,A(原子性)、I(隔离性)、D(持久性)是手段,是为了保证一致性,数据库提供的手段。数据库必须要实现AID三大特性,才有可能实现一致性。例如,原子性无法保证,显然一致性也无法保证。
从应用层面,通过代码判断数据库数据是否有效,然后决定回滚还是提交数据!
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。