显式事务与隐式事务
- 对于单条SQL语句,数据库系统自动将其作为一个事务执行,这种事务被称为隐式事务
- 手动把多条SQL语句作为一个事务执行,使用
BEGIN开启一个事务,使用COMMIT提交一个事务,这种事务被称为显式事务
事务的四个特性
原子性
将所有SQL作为原子工作单元执行,要么全部执行,要么全部不执行
一致性
事务完成后,数据状态的改变是一致的,结果是完整的
隔离性
事务与事务试图操纵同样数据时,他们之间是互相隔离的
如果有多个事务并发执行,每个事务作出的修改必须与其他事务隔离
持久性
事务提交后,数据结果会永久保存,也即完成数据持久化,即使断电数据也已经保存
隔离级别与数据读取问题
脏读(Read Uncommitted)
在这种隔离级别下,一个事务会读到另一个事务更新后但未提交的数据,如果另一个事务回滚,那么当前事务读到的数据就是脏数据
例如:
A事务修改了一条数据,但是未提交修改,此时A事务对数据的修改对其他事务是可见的,B事务中能够读取A事务未提交的修改。一旦A事务回滚,B事务中读取的就是不正确的数据
不可重复读(Read Committed)
一个事务先后采用相同的策略读取数据,发现两次读取的数据不一致
详细解释:在一个事务内,多次读同一数据,在这个事务还没有结束时,如果另一个事务恰好修改了这个数据,那么,在第一个事务中,两次读取的数据就可能不一致
例如:
- A事务中读取一行数据
- B事务中修改了该行数据
- A事务中再次读取该行数据将得到不同的结果
幻读(Repeatable Read)
一个事务按照相同的条件查询数据,却发现其他事务插入了满足其查询条件的数据
详细解释:在一个事务中,第一次查询某条记录,发现没有,但是,当试图更新这条不存在的记录时,竟然能成功,并且,再次读取同一条记录,它就神奇地出现了
例如:
- A事务中通过WHERE条件读取若干行
- B事务中插入了符合条件的若干条数据
- A事务中通过相同的条件再次读取数据时将会读取到B事务中插入的数据。
此外隔离级别还有Serializable,最严格的隔离级别,但效率最低
参考
- 事务
- MyBatis 3源码深度解析/江荣波