一个或一组SQL语句组成一个执行单元,要求同时成功或同时失败。部分存储引擎(InnoDB)可以支持事务功能。
事务的特点(也就是事务的ACID属性):
- 原子性,就是不可分割。
- 一致性,就是符合逻辑,比如转账前后双方总金额不变;提现之后,余额要减少。
- 隔离性,就是互不干扰,一个事务内部的操作及数据对并发的其他事务是隔离的,可用隔离级别微调。当然,没有并发就谈不上隔离。
- 持久性,就是不能后悔,无论是其他操作还是数据库故障,都不能影响已经提交的事务(无法篡改历史)。
事务的创建
原始的增删改查单条语句本身就是一个事务,叫隐性事务,数据库会自动创建。显式事务就需要自行添加事务相关的指令了。
开发过程中,框架会根据代码的逻辑自动的生成带事务指令的SQL语句,比如设置自动提交的参数,自动添加开启事务、回滚事务和提交事务的指令等。
开启事务的指令中必须存在“SET AUTOCOMMIT = 0;”,“START TRANSACTION;”则可有可无。
事务隔离性
隔离性引发的问题:
- 脏读:读了临时的数据。B事务修改了但没提交,最后回滚了的数据,A事务读取了无效的数据。
- 幻读:读了多出的数据。B事务插入了数据,A事务过程中读了两次发现多了些数据。
- 不可重复读:读了不同的数据。B事务修改了数据,A事务过程中读了两次发现数据不一样了。
对应问题,数据库有4种事务隔离级别:
- 读未提交:不设限制,随意读取。
- 读已提交:只允许事务读取别的事务已经提交的数据,避免脏读。
- 可重复读:某事务读取过程中不许其他事务修改(插入并不算修改数据),可避免脏读和不可重复读。
- 串行读取:某事物读取某表时,不许其他事务动这张表,效率极低。