事务的特性
- 原子性(Atomicity).一个事务是一个不可分割的工作单位,一个事务中的所有操作,要么全部完成,要么全部不完成,没有中间状态。事务执行过程中出错,会回滚到事务开始前的状态
- 一致性(Consistency).事务开始前和结束后的数据完整性保持一致
- 隔离性(Isolation).一个事务执行的过程中,不能受到其他事务的干扰
- 持久性(Durability).事务一旦提交,数据就持久化到数据库
事务的运行模式
- 自动提交事务:一个语句为一个事务
- 显示事务:使用begin transaction 开始事务,以commit或rollback回滚结束事务
- 隐式事务:sql会在提交或回滚时自动开启新事物,无需手动开启事务,只需手动提交或回滚事务
事务的隔离级别
- 读未提交(read uncommitted)
一个事务可以读到另一个事务未提交事务的数据。例如,小张准备给小李转1万,只是在atm机上输入了1万,还没有点立即转账,事务还没提交,这时小李查看余额,发现卡里已经多了一万,这就是脏读
- 读已提交(read commited)
一个事务只能读到其他事务已经提交的数据。例如,小张正准备使用微信支付付款10元,点击付款,此时事务开启,手机显示他余额为10元,此时小张老婆使用亲情卡消费5元,小张点击立即付款,发现余额不足。一个事务范围内两个相同的查询却返回了不同的数据,这就是不可重复读。大多数据库的默认级别是read committed
- 重复读(repeatable read)
事务开启后,不再允许其他事务对数据的的写操作。例如,小张正准备使用微信支付付款10元,点击付款,此时事务开启,手机显示他余额为10元,此时小张老婆准备使用亲情卡消费5元,发现无法支付。这就是重复读,重复读可以解决不可重复读的问题。但是还会出现幻读的问题,因为重复读只是在行级别加锁,锁住的是UPDATE操作,无法阻止INSERT操作
幻读:小张查看微信账单,发现有10条记录,点击导出之前,小张老婆使用亲情卡产生了一笔消费,小张导出账单发现有11条消费记录,方法产生了幻觉一样,这就是幻读。如何解决幻读呢?Serializable!
- 序列化(serializable)
serializable是最高的事务隔离级别,在该级别下,事务串行化顺序执行,可以避免脏读、不可重复读与幻读。但这种事务隔离级别效率低下,一般不使用。