1.事务的四大特性(ACID)
1)原子性
一个事务中的操作要么全部都做,要么全部都不做
mysql通过undo log(回滚日志)实现事务的原子性
所有对数据库的写操作,会先写到回滚日志中,然后在写到数据库中。当发生回滚时,会按照日志逻辑地将数据库中的修改撤销掉,可以理解为,在事务中使用的每一条insert对应了一条delete,每一条update对应一条相反的update
2)一致性
事务保证只能从一个一致性状态转变到另外一个一致性状态
比如A,B账户合起来一共有5000元,那么完成A,B转账的事务以后,两个账户总额仍然为5000元
3)隔离性
4)持久性
事务完成以后(即commit之后)对数据库的改变将永久存在
2.事务的四大隔离级别
1)未提交读
一个事务可以读取到未提交事务中的数据
2)提交读
一个事务只能读取提交的
3)可重复读
4)串行化
事务之间对于写操作具有排他性,一次只能有一个事务对数据进行写操作
事务的隔离级别1->4逐渐变高
系统开销1->4逐渐增加
即事务隔离级别越高,系统开销越高,出现数据出错的概率也越小,但是并发度越小,不利于高并发查多写少的应用场景
InnoDB存储引擎的默认事务隔离级别为可重复读,因为可重复读带来的幻读问题条件比较苛刻,与串行化相比,其系统开销更小以及对并发处理更好。
3.事务可能带来的问题
1)脏读
一个事务读取到另外一个未提交事务的中间数据
2)不可重复读
一个事务因为另外一个事务的update(该事务已提交)导致两次相同操作读取到的数据不一样
不可重复读是因为事务的update导致的
3)幻读
一个事务因外另外一个事务的delete/insert(该事务已提交)导致两次相同操作读取到的数据不一样
幻读是因为事务的delete和insert导致的
未提交读会带来脏读、不可重复读、幻读问题
提交读解决了脏读问题,但是会带来不可重复读、幻读问题
可重复读解决了脏读、不可重复读的问题,仍然还有幻读不能解决
串行化解决了所有问题
因此事务隔离级别越高,带来的问题越少
4.封锁协议和事务隔离级别的关系
事务隔离级别是封锁协议的应用
1)一次封锁协议
已经预先知道需要使用哪些数据,将这些数据全部加锁,运行以后再释放锁。但在mysql事务中我们不会预先知道需要使用哪些数据,因此不适用
2)二段锁协议
将事务分为加锁和释放锁阶段,在加锁阶段不能释放锁,在释放锁阶段不能加锁。
加锁阶段对写操作加x锁(排他锁,其他事务不能继续加任何锁)
对所有读操作加s锁(共享锁,其他事务可以继续加s锁,但不能加x锁)
锁的种类:行锁、表锁
未提交读:对任何操作不加任何锁
提交读:只对delete\update\insert加锁,对select不加任何锁
可重复读:
可串行:对select加s锁,对delete\update\insert加x锁。有点类似于java并发中的读写锁