一、基本概念
数据库事务(简称:事务)是数据库管理系统执行过程中的一个逻辑单位,由一个有限的数据库操作序列构成
概要:
一个数据库事务通常包含了一个序列的对数据库的读/写操作。
它的存在包含有以下两个目的:
1、为数据库操作序列提供了一个从失败中恢复到正常状态的方法,同时提供了数据库即使在异常状态下仍能保持一致性的方法。
事务的四大特性:
简称:ACID
原子性(Atomicity):事务作为一个整体被执行,包含在其中的对数据库的操作要么全部被执行,要么都不执行。
一致性(Consistency):事务应确保数据库的状态从一个一致状态转变为另一个一致状态,一致状态的含义是数据库中的数据应满足完整性约束。
隔离性(Isolation):多个事务并发执行时,一个事务的执行不应影响其他事务的执行。
持久性(Durability):已被提交的事务对数据库的修改应该永久保存在数据库中。
二、事务的隔离级别
事务隔离级别的统计
事务级别 | 脏读 | 不可重复读 | 幻读 |
未提交读 | Yes | Yes | Yes |
提交读 | No | Yes | Yes |
可重复读 | No | No | Yes |
串行读 | No | No | No |
未提交读(Read Uncommitted):允许脏读,也就是可能读取到其他会话中未提交事务修改的数据
事例:
老板要给程序员发工资,程序员的工资是5000/月。但是发工资时老板不小心按错了数字,按成8000/月,该钱已经打到程序员的户口,但是事务还没有提交,就在这时,程序员去查看自己这个月的工资,发现比往常多了3千元,以为涨工资了非常高兴。但是老板及时发现了不对,马上回滚差点就提交了的事务,将数字改成5000再提交。
分析:
实际程序员这个月的工资还是5000,但是程序员看到的是8000。他看到的是老板还没提交事务时的数据。这就是脏读。
提交读(Read Committed):只能读取到已经提交的数据。Oracle等多数数据库默认都是该级别(不重复读)
事例:
当你准备买东西,检测的时候你卡里有10000元,但是此时你的妻子因为别的事,把这一万元给转出来了,当你支付的时候你发现卡里并没有钱。
分析:这就是读未提交,读要等到事务更新完了提交事务才能读取数据,这样可以解决脏读。
可重复读(Repeated Read):可重复复。在同一事务内的查询都是事务开始时刻一致的,InnoDB默认级别。在SQL标准中,该隔离级别消除了不可重复读,但是还存在幻象读
事例:
程序员某一天去消费,花了2千元,然后他的妻子去查看他今天的消费记录(全表扫描FTS,妻子事务开启),看到确实是花了2千元,就在这个时候,程序员花了1万买了一部电脑,即新增INSERT了一条消费记录,并提交。当妻子打印程序员的消费记录清单时(妻子事务提交),发现花了1.2万元,似乎出现了幻觉,这就是幻读。
串行读(Serializable):完全串行化的读,每次读都需要获得表级共享锁,读写相互都会阻塞
Serializable 是最高的事务隔离级别,在该级别下,事务串行化顺序执行,可以避免脏读、不可重复读与幻读。但是这种事务隔离级别效率低下,比较耗数据库性能,一般不使用。
小结:
数据库通常默认的是提交读,例如Oracle、SQL Server等。Mysql是可重复读
例题:
下面有关事务隔离级别说法正确的是()
A、未提交读:允许脏读,也就是可能读取到其他会话未提交事务修改的数据
B、提交读:只能读取到已经提交的数据
C、可重复读:在同一事务内查询都是事务开始时刻一致的
D、串行读:完全串化读,每次读都要获得共享锁,读写相互都会阻塞
上面为网易笔试题,答案:ABCD