事务是指一组原子性的SQL操作,在数据库中,事务作为一个最小的工作单元存在
事务的特性
一个事务必须遵循ACID原则
- 原子性(atomicity) 事务作为最小的一个工作单元,每个事务中包含的所有操作,要么全部成功,要么全部失败
- 一致性(consistency) 数据库总是会从一个一致性状态到另一个一致性状态,事务在操作过程中如果中断,做出的部分修改不会被保存
- 隔离性(isolation) 事务A做出部分修改之后,事务B一般不会看到A所做出的改变(在未提交读隔离级别产生的脏读以及可串行化之下的隔离级别产生的幻读场景下仍然可以看到)
- 持久性(durability) 一旦事务提交,事务提交的数据就会被记录在数据库中持久存储
隔离级别
- 未提交读(READ UNCOMMITED) 事务中的修改即使没有提交,对其他事务也是可见的
- 已提交读(READ COMMITED) 一个事务从开始到提交,所做的任何操作对其他事务都不可见,但是执行两次同样的查询得到的结果可能不同,是大部分数据库的默认隔离级别
- 可重复读(REPEATABLE READ) 一个事务从开始到提交,所做的任何操作对其他事物都不可见,执行多次同样的查询语句得到的结果一致,这是MySQL数据库的默认隔离级别
- 可串行化(SERIALIZABLE) 强制事务串行执行,在读取的每一条数据上都加锁
读取问题
- 脏读 事务可以读取未提交的数据
- 幻读 当事务在读取某个范围内的记录是,另外一个事务又在该范围内插入了新的记录,之前的事务再次读取该范围内的记录是会产生换行
死锁
两个或多个事务在一对资源上相互占用,并且请求占用对方的资源,从而导致恶性循环
InnoDB会在锁超过等待超时的设定后自动回滚持有行级排它锁最少的事务
MySQL中的事务
MySQL采用AUTOCOMMIT自动提交模式,每一个语句都会被当做一个事务进行操作提交,可以手动设置不自动提交
1
set AUTOCOMMIT=1;
并且可以手动进行设定隔离级别
1
set SEESION TRANSACTION ISOLATION LEVEL READ COMMIT;
由于事务的处理是由MySQL的第三层,也就是存储引擎实现的,所以跨引擎的事务是不可靠的
- InnoDB引擎的锁采用二阶段锁定协议,在事务执行的过程中随时都可以执行加锁,在COMMIT或者ROLLBACK时同时释放所有锁