数据库若是支持事务,就要知足下面四个特性(ACID)。mysql
原子性(A:Atomicity)sql
在一个事务中,多个sql操做,要么一块儿成功(全部数据操做都成功),要么一块儿回滚(其中一个没有成功,其余数据操做一块儿恢复到开始状态)。数据库
一致性(C:Consistency)服务器
数据修改前是准确的,修改后也要说准确的。指的是数据从一个一致性状态,转换到另外一种一致性的状态。(例如:A和B总共有10个苹果,A转让了几个苹果给B,事务结束后,A和B总共仍是10个苹果)。并发
隔离性(I:Isolation)性能
当数据库有多个事务一块儿执行时,各个事务之间互相不影响,每一个事务感知不到有其余的事务在执行。spa
持久性(D:Durability)blog
数据库事务结束提交后,数据修改永久有效,即便数据库重启,遇到其余问题关掉,再打开后,以前提交过的数据的修改仍是生效的(例如:程序执行数据的操做,事务提交后,忽然数据库服务器断电等缘由致使数据库停掉不可用,恢复后,数据仍是修改后的状态)。事务
读未提交ci
两个事务同时操做数据库,其中一个事物修改数据库后,没有提交,另外一个事物能够读取到修改过的数据。
读已提交
有两个事务,第一个事务查询一条数据,第二个事务修改这条数据提交后,第一个事务又查询该数据,第一个事务先后两次查询的结果不一致。
可重复读(mysql默认隔离级别,经过MVCC<Mutil-Version Concurrency Control>机制实现)
有两个事务,第一个事务查询一条数据,第二个事务修改这条数据提交后(出于性能考虑,使用了以乐观锁为理论基础的MVCC<多版本并发控制>来实现),第一个事务又查询该数据,第一个事务先后两次查询的结果不致。
串行化(解决 幻读 的问题)
可重复读能够限制两个事务并发修改删除数据致使先后查询不一致的状况,可是没法限制insert(行锁只能锁住行,新增数据没法限制)。
幻读的案例场景:有两个事务,第一个数据查询列表数据条数,第二个事务新增数据到表中并提交事务,第一个事务又从新查询数据条数,第一个事务先后两次查询的数据不一致。
串行化:有两个事务,第一个事务查询数据,第二个事务新增数据到表中,会报错(表级锁),不能插入数据,第一个事务再查询数据,先后两次结果一致。串行化并发低。
MVCC原理简介:
经过事务id控制不一样版本数据(由于经过事务id控制数据,因此下面数据中id也是会重复的),sql查询的时候,后两列隐藏列不会显示。下列表格对应的事务开始顺序与数字大小顺序一致,最终全部事务一块儿结束。(经过并发状况简单说明MVCC原理)
事务id=1插入数据;事务id=3插入数据;事务id=4删除数据;事务id=5修改数据;表最终数据以下:
id 数据 更新事务ID(隐藏列) 删除事务ID(隐藏列) 1 张三 1 4 2 小明 1 空 3 李四 1 空 4 王五 3 空 2 小明111 5 空
事务id=2,查询全表数据,查询数据以下:
start transaction; select * from a; //(1) select * from a; //(2) commit;
假设:
事务id=2中(1)查询发生在事务id=1以后 ;
事务id=2中(2)查询发生在事务id=3插入数据以后;
事务id=2两次查询结果都一
样(经过事务id作了限制,只会查询小于等于当前事务id的数据)
id 数据 更新事务ID(隐藏列) 删除事务ID(隐藏列) 1 张三 1 空 2 小明 1 空 3 李四 1 空
假设:
事务id=2中(1)查询发生在事务id=1以后 ;
事务id=2中(2)查询发生在事务id=4删除数据以后;
事务id=2两次查询结果都同样(经过事务id作了限制,只会查询小于等于当前事务id的数据)
id 数据 更新事务ID(隐藏列) 删除事务ID(隐藏列) 1 张三 1 4 2 小明 1 空 3 李四 1 空
假设:
事务id=2中(1)查询发生在事务id=1以后 ;
事务id=2中(2)查询发生在事务id=5修改数据以后(修改也至关于插入一条数据,数据的事务id是不一样的);
事务id=2两次查询结果都同样(经过事务id作了限制,只会查询小于等于当前事务id的数据)
数据 更新事务ID(隐藏列) 删除事务ID(隐藏列) 1 张三 1 空 2 小明 1 空 3 李四 1 空