ACID 是数据库管理系统(DBMS)中用来确保事务处理正确性和可靠性的四个特性的首字母缩写。ACID 是指原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)和持久性(Durability)。
- 原子性(Atomicity):原子性要求一个事务被视为一个不可分割的最小操作单元,要么全部执行成功,要么全部回滚到事务开始前的状态。即使在发生错误或异常的情况下,也不能只执行部分操作。原子性保证了事务的完整性,如果任何操作失败,所有已经执行的操作都将被撤销,数据库状态会回滚到事务开始前的一致状态。
- 一致性(Consistency):一致性指的是在事务开始和结束时,数据库必须保持一致状态。这意味着事务必须遵循预定义的规则和约束条件,不会破坏数据库的完整性。一致性确保了数据的有效性和正确性。
- 隔离性(Isolation):隔离性规定了同时执行的多个事务之间应该是相互隔离的,每个事务应该感觉不到其他事务的存在。隔离性主要关注并发事务之间可能产生的问题,如脏读(Dirty Read)、不可重复读(Non-repeatable Read)、幻读(Phantom Read)等。通过隔离级别的设置,可以控制事务之间的隔离程度,确保事务并发执行时的数据一致性。
- 持久性(Durability):持久性要求一旦事务提交成功,对数据库的修改就是永久性的,即使在系统故障或崩溃的情况下也不会丢失。为了实现持久性,DBMS 将事务的日志记录到非易失性的存储介质(如磁盘)上,确保在系统恢复后可以将数据还原到提交事务的状态。
ACID 事务的特性保证了数据库中的事务处理是可靠和可靠的。通过将一系列操作组装成一个事务,并遵循 ACID 特性,可以确保数据库在并发环境下能够正确处理数据,并保持数据的一致性和完整性。
隔离性
说到隔离性首先是四种隔离级别
- READ UNCOMMITTED(未提交读RU):一个事务还没提交时,它做的变更就能被别的事务看到
- READ COMMITTED(已提交读RC):一个事务提交之后,它做的变更才会被其他事务看到
- REPEATABLE READ(可重复读RR):一个事务中,对同一份数据的读取结果总是相同的,无论是否有其他事务对这份数据进行操作,以及这个事务是否提交。 InnoDB默认级别 。
- SERIALIZABLE(串行化):事务串行化执行,每次读都需要获得表级共享锁,读写相互都会阻塞,隔离级别最高,牺牲系统并发性。
这四大等级从上到下,隔离的效果是逐渐增强,但是性能却是越来越差。
不同的隔离级别是为了解决不同的问题
那么不同的隔离级别,隔离性是如何实现的,为什么不同事物间能够互不干扰? 答案是 锁 和 MVCC。
隔离级别的设置
查看当前的隔离级别
select @@transaction_isolation;
临时设置隔离级别
SET TRANSACTION ISOLATION LEVEL <隔离级别>;
永久设置隔离级别
transaction_isolation = <隔离级别>
事务的管理
开启事务
begin/start transaction
提交事务
commit
回滚事务
rollback
原子性
接着说说原子性。前文有提到 undo log ,回滚日志。隔离性的MVCC其实就是依靠它来实现的,原子性也是。 实现原子性的关键,是当事务回滚时能够撤销所有已经成功执行的sql语句。 当事务对数据库进行修改时,InnoDB会生成对应的 undo log;如果事务执行失败或调用了 rollback,导致事务需要回滚,便可以利用 undo log 中的信息将数据回滚到修改之前的样子。 undo log 属于逻辑日志,它记录的是sql执行相关的信息。当发生回滚时,InnoDB 会根据 undo log 的内容做与之前相反的工作:
- 对于每个 insert,回滚时会执行 delete;
- 对于每个 delete,回滚时会执行insert;
- 对于每个 update,回滚时会执行一个相反的 update,把数据改回去。
以update操作为例:当事务执行update时,其生成的undo log中会包含被修改行的主键(以便知道修改了哪些行)、修改了哪些列、这些列在修改前后的值等信息,回滚时便可以使用这些信息将数据还原到update之前的状态。
一致性
一致性是事务追求的最终目标,前文所诉的原子性、持久性和隔离性,其实都是为了保证数据库状态的一致性。 当然,上文都是数据库层面的保障,一致性的实现也需要应用层面进行保障。 也就是你的业务,比如购买操作只扣除用户的余额,不减库存,肯定无法保证状态的一致。
持久性
Innnodb有很多 log,持久性靠的是 redo log。