事务讲解

101 阅读4分钟

事务的四个特性(ACID)

原子性:事务是一个原子性操作,一个事务由一系列操作组成,这一系列操作要么全部执行完成,要么全部不执行
一致性:一个事务执行完成(不管成功还是失败),数据库的完整性不能被破坏(唯一约束,外键约束等)
隔离性:数据库允许多个并发事务同时对数据进行读写操作,隔离性可以防止这些操作同时执行时导致的数据不一致的问题。
事务分为不同的隔离级别:
读未提交(read uncommitted)、
读已提交(read committed)、
可重复读(repeatable read)--mysql默认隔离级别
和串行化(Serializable)
持久性:持久性意味着事务完成之后,该事物对数据的更改会永久的保存在数据库中。
隔离级别有四种
分别是:读未提交、读已提交、可重复读、序列化。\

1、Read uncommitted

读未提交,顾名思义,就是一个事务可以读取另一个未提交事务的数据。存在(脏读、不可重复读、幻读、丢失更新)问题

1)脏读:一个事务读取到另一个事务中没有提交的数据;\

【举例】:A给B发1000块钱,手一抖打了10000,这个钱已经打到B的户口,但是事务还没有提交,这时B查下卡,发现多了9000,兴奋坏了,但是A及时发现,马上回滚差点提交的事务,将数字改回1000再提交。\

2、Read committed

读提交,顾名思义,就是一个事务要等另一个事务提交后才能读取数据。存在(不可重复读、幻读、丢失更新)问题

存在不可重复读问题:同一事务的其他实例在该实例处理其间可能会有新的commit,所以同一select可能返回不同结果。
2)不可重复读(虚读):在同一个事务中两次读取到的数据不一样;\

【举例】:A拿着卡去购物,卡里有1000块钱,当A买单时(事务开启),收费系统事先检测到他的卡里有1000,就在这个时候,A的妻子要把钱全部拿出来买首饰,并提交。当收费系统准备扣款时,再检测卡里的金额,发现已经没钱了(第二次检测金额当然要等待A的妻子转出金额事务提交完),A就会很郁闷,钱哪去了。。。\

3、Repeatable read

重复读,就是在开始读取数据(事务开启)时,不再允许修改操作存在(幻读、丢失更新)问题
存在幻读问题:幻读指当用户读取某一范围的数据行时,另一个事务又在该范围内插入了新行,当用户再读取该范围的数据行时,会发现有新的“幻影” 行。
InnoDB存储引擎通过多版本并发控制(MVCC,Multiversion Concurrency Control)机制解决了该问题。
3)幻读:一个事务操作(DML)数据表中所有的记录,另一个事务添加/删除了一条数据,则第一个事务查询不到自己的修改;
事务A 新增了一条记录,事务B 在 事务A 提交前后各执行了一次查询操作,发现后一次比前一次多了一条记录。幻读出现的原因就是由于事务并发新增记录而导致的
【举例】:A去消费,花了1千元,A的妻子去查看他今天的消费记录(全表扫描FTS,妻子事务开启),看到确实是花了1千元,就在这时,A又花了1千元买了一个机械键盘,即新增INSERT了一条消费记录,并提交。当妻子打印消费记录清单时(妻子事务提交),发现花了2千元,似乎出现了幻觉,这就是幻读。\

4、Serializable 序列化

最高的事务隔离级别,在该级别下,事务串行化顺序执行,可以避免脏读、不可重复读与幻读

丢失更新(lost update)发生在事务T1和T2同时尝试更新V的值时。T1和T2读取V的值。T1更新V并提交,之后T2也更新V并提交。由于这两个事务不知道彼此的存在,所以如果允许二者都提交,则T1的结果将被T2的结果覆盖,T1的更新将丢失。

脏写(dirty write)指的是某个事务拿到了一个未提交的值(即脏读),对其进行修改并保存。换句话说,事务结果来自从未提交过的值。