17.Mysql之事务浅谈
1.前言
我们总是在比较Mysql的存储引擎时说innodb存储引擎支持事务,而Myisam存储引擎不支持事务,那么到底什么是事务呢?
2.事务特性
事务可由一条非常简单的SQL语句组成,也可以由一组复杂的SQL语句组成。事务是访问并更新数据库中各种数据项的一个程序执行单元,在事务中的操作,要么都做修改,要么都不做,这就是事务的目的。
innodb存储引擎的事务的四大特性:ACID特性。
- 原子性(atomicity):原子性指整个数据库事务是不可分割的工作单位。只有使事务中所有的数据库操作都执行成功,才算整个事务成功。事务中任何一个SQL语句执行失败,已经执行成功的SQL也必须撤销,数据库状态应该退回到执行事务前的状态(简言之:要么都执行成功,要么都执行失败)
- 一致性(consistency):一致性指事务将数据库从一种状态转变为下一种一致性状态,在事务开始之前和事务结束之后,事务库的完整性约束没有被破坏。比如说在表中有一个字段为姓名,为唯一约束,即在表中姓名不能重复。如果一个事务对姓名字段进行了修改,但是在事务提交或回滚后,表中的姓名变得非唯一,这就破坏了事务的一致性要求了。即事务将数据库从一种状态边为了一种不一致的状态。
- 隔离性(isolation)。隔离性还有其他称呼,如并发控制。可串行化、锁等。事务的隔离性要求每个读写事务的对象对其他事务的操作对象能相互分离。即该事务提交前对其他事务都是不可见的。
- 持久性(durability):事务一旦提交,其结果就是永久的。即使发生宕机等故障。数据库也能将数据恢复。
3.标准的事务隔离级别
在数据库中标准的事务隔离级别有如下几种:
- 未提交读(READ-UNCOMMITTED):对应的异常现象就是脏读(Dirty read),事务A可以读取到未提交的事务B的信息
- 读已提交(READ-COMMITTED):对应的现象是不可重复读(Non-repeatable read)以及出现幻读现象,事务 A 多次读取同一数据,事务 B 在事务A多次读取的过程中,对数据作了更新并提交,导致事务A多次读取同一数据时,结果 不一致。
- 可重复读(REPEATABLE-READ):解决了脏读和不可重复读的现象,但是可能会产生幻读现象。
- 可序列化(SERIALIZABLE):
说明:在当前mysql默认的隔离级别中也就是可重复读的隔离级别中,如果检索条件有索引(包括主键索引)的时候,默认加锁方式是next-key 锁;如果检索条件没有索引,更新数据时会锁住整张表。一个间隙被事务加了锁,其他事务是不能在这个间隙插入记录的,这样可以防止幻读。
4.事务管理:
在Mysql中默认是自动提交事务的,可以通过以下方式手动开启事务:
- 执行begin语句
- 执行start transaction语句
- 设置autocommit=0
可以通过以下4种方式提交事务:
- 执行commit语句
- DDL语句隐式提交
- 自动提交(autocommit)
- 在事务内开始事务
事务的回滚方式如下:
- 执行rollback方式
- 因达到超时时间而发生语句级或者事务级的回滚
- 检测到死锁是发生回滚
总结:在Mysql中,我们需要注意事务中各个子句之间是相互独立的互补影响,在执行过程中报错的语句发生了回滚,但是对于整个事务中已经执行成功的语句无影响。
经典问题:
总结中的这一段话是否和事务的原子性特征互相矛盾呢?