1. 概述
事务是数据库区别于文件系统的重要特性之一。事务会把数据库从一种一致状态转换为另一种一致状态。在数据库提交工作时,可以确保要么所有修改都已经保存了,要么所有修改都不保存。
2. ACID属性
事务是由一组SQL语句组成的逻辑处理单元,事务具有以下4个属性,通常简称为事务的ACID属性。
- 原子性(Atomicity) :事务是一个原子操作单元,其对数据的修改,要么全都执行,要么全都不执行。
- 一致性(Consistent) :在事务开始和完成时,数据都必须保持一致状态。这意味着所有相关的数据规 则都必须应用于事务的修改,以保持数据的完整性。
- 隔离性(Isolation) :数据库系统提供一定的隔离机制,保证事务在不受外部并发操作影响的“独 立”环境执行。这意味着事务处理过程中的中间状态对外部是不可见的,反之亦然。
- 持久性(Durable) :事务完成之后,它对于数据的修改是永久性的,即使出现系统故障也能够保持。
3. 事务的实现
事务的隔离性有锁来实现,原子性、持久性有redolog实现,一致性有undolog实现。
4. 事务控制语句
- start transaction | begin:开启事务
- commit:提交事务
- rollback:回滚
- set transaction:设置事务的隔离级别。InnoDB存储引擎提供的事务隔离级别有:读未提交(read uncommitted)、读已提交(read committed)、可重复读(repeatable read)和serializable(串行化)。
5. 并发事务处理带来的问题
- 更新丢失(Lost Update)或脏写:当两个或多个事务选择同一行,然后基于最初选定的值更新该行时,由于每个事务都不知道其他事务的存在,就会发生丢失更新问题–最后的更新覆盖了由其他事务所做的更新。
- 脏读:事务A读取到了事务B已经修改但尚未提交的数据,还在这个数据基础上做了操作。此时,如果B 事务回滚,A读取的数据无效,不符合一致性要求。
- 不可重读(Non-Repeatable Reads):事务A内部的相同查询语句在不同时刻读出的结果不一致,不符合隔离性
- 幻读:事务A读取到了事务B提交的新增数据,不符合隔离性
数据库提供以下四种隔离级别,不同的隔离级别会解决不同的问题。
常看当前数据库的事务隔离级别: show variables like 'tx_isolation';
Mysql默认的事务隔离级别是可重复读,用Spring开发程序时,如果不设置隔离级别默认用Mysql设置的隔 离级别,如果Spring设置了就用已经设置的隔离级别。