Open TENCHIANG opened 5 years ago
事务(Transaction)指的是满足 ACID 特性的一组操作,可以通过 Commit 提交一个事务,也可以使用 Rollback 进行回滚。
ACID分别是:原子性(atomicity,或称不可分割性)、一致性(consistency)、隔离性(isolation,又称独立性)、持久性(durability)。
一个事务包含多个操作视为一个原子整体,事务内所有操作要么全部完成,要么某一个操作失败而整个事务失败并回滚(Rollback),就像没有执行过事务一样,不能只执行其中一些操作。 回滚可以用回滚日志来实现,回滚日志记录着事务所执行的修改操作,在回滚时反向执行这些修改操作即可。
这里的一致性很容易搞混,一致性有很多种一致性(他们都互不相同):
ACID的一致性,可以理解为应用系统从一个正确的状态到另一个正确的状态。而ACID就是说事务能够通过AID来保证这个C的过程,C是目的,AID都是手段。
事务之间互相影响的程度或者说事务间的可见性(特别是并发任务),比如一个事务会不会读取到另一个未提交的事务修改的数据。
一致性和并发性能不可兼得,在实际应用中应做一些取舍,适当的破坏一致性来提升性能与并行度,这就是
隔离级别严格程度由低到高 隔离级别的特性就是它的问题,它的问题就是它的特性
未提交读(Read uncommitted) 一个事务可以读到另一个事务未提交或已撤销的结果(脏读)。所有的并发事务问题都会发生。 事务未提交和已撤销是一个东西。
提交读(Read committed) 一个事务只能读取已经提交的事务所做的修改 -> 一个事务所做的修改在提交之前对其它事务是不可见的 -> 两次查询可能会得到不一样的结果(因为别的事务的提交),所以又称 不可重复读 可以解决脏读问题。 大部分数据库默认的隔离级别是 提交读,MySQL是 可重复读。
可重复读(Repeatable read) 保证在同一个事务中多次读取同样数据的结果是一样的,无论是否有其他事务对这份数据进行操作,以及这个事务是否提交。可以解决脏读、不可重复读,但是不能解决 幻读(Phantom read) 。 InnoDB和XtraDB存储引擎可通过 多版本并发控制(MVCC, Multiversion Concurrency Control) 解决幻读问题。
串行化(Serializable) 事务串行化执行,隔离级别最高,牺牲了系统的并发性。可以解决并发事务的所有问题。 需要加锁实现,而其它隔离级别通常不需要(所谓加锁读?)。
隔离级别越低,并发性越好,系统开销越低,因为要做的操作或者约束越少。
事务一旦提交,那么就会执行成功永久生效,或者发生错误回滚如初,不会因为数据库崩溃而改变。 使用重做日志来保证持久性。 持久性也分很多种级别。
事务(Transaction)指的是满足 ACID 特性的一组操作,可以通过 Commit 提交一个事务,也可以使用 Rollback 进行回滚。
ACID分别是:原子性(atomicity,或称不可分割性)、一致性(consistency)、隔离性(isolation,又称独立性)、持久性(durability)。
A: 原子性(Atomicity,或称不可分割性)
一个事务包含多个操作视为一个原子整体,事务内所有操作要么全部完成,要么某一个操作失败而整个事务失败并回滚(Rollback),就像没有执行过事务一样,不能只执行其中一些操作。 回滚可以用回滚日志来实现,回滚日志记录着事务所执行的修改操作,在回滚时反向执行这些修改操作即可。
C: 一致性(Consistency)
这里的一致性很容易搞混,一致性有很多种一致性(他们都互不相同):
ACID的一致性,可以理解为应用系统从一个正确的状态到另一个正确的状态。而ACID就是说事务能够通过AID来保证这个C的过程,C是目的,AID都是手段。
I: 隔离性(Isolation,又称独立性)
事务之间互相影响的程度或者说事务间的可见性(特别是并发任务),比如一个事务会不会读取到另一个未提交的事务修改的数据。
事务在并发情况下可能会出现的问题
一致性和并发性能不可兼得,在实际应用中应做一些取舍,适当的破坏一致性来提升性能与并行度,这就是
隔离级别(Isolation level)
隔离级别严格程度由低到高 隔离级别的特性就是它的问题,它的问题就是它的特性
未提交读(Read uncommitted) 一个事务可以读到另一个事务未提交或已撤销的结果(脏读)。所有的并发事务问题都会发生。 事务未提交和已撤销是一个东西。
提交读(Read committed) 一个事务只能读取已经提交的事务所做的修改 -> 一个事务所做的修改在提交之前对其它事务是不可见的 -> 两次查询可能会得到不一样的结果(因为别的事务的提交),所以又称 不可重复读 可以解决脏读问题。 大部分数据库默认的隔离级别是 提交读,MySQL是 可重复读。
可重复读(Repeatable read) 保证在同一个事务中多次读取同样数据的结果是一样的,无论是否有其他事务对这份数据进行操作,以及这个事务是否提交。可以解决脏读、不可重复读,但是不能解决 幻读(Phantom read) 。 InnoDB和XtraDB存储引擎可通过 多版本并发控制(MVCC, Multiversion Concurrency Control) 解决幻读问题。
串行化(Serializable) 事务串行化执行,隔离级别最高,牺牲了系统的并发性。可以解决并发事务的所有问题。 需要加锁实现,而其它隔离级别通常不需要(所谓加锁读?)。
隔离级别越低,并发性越好,系统开销越低,因为要做的操作或者约束越少。
D: 持久性(Durability)
事务一旦提交,那么就会执行成功永久生效,或者发生错误回滚如初,不会因为数据库崩溃而改变。 使用重做日志来保证持久性。 持久性也分很多种级别。