MySQL——事务
目录
MySQL之事务
一、什么是事务?
事务定义:事务是逻辑上的一组操作,要么都执行,要么都不执行。
事务举例:转账。
A向B转账100元,会有两个操作,① A的账户减少100元,②B的账户增加100元。
如果在这两个操作之间发生了问题,也就是①操作完成了,②操作还未完成 的时候发生了问题。比如服务器死机了。
那就会造成,A的账户减少了100元,但B的账户却没有增加100元。这就出大问题了。
而事务可以保证这两个操作,要么都成功,要么都失败。
二、事务的特性(ACID)?
事务的四个特性,简称ACID。
ACID 具体是指:
- 原子性(Atomistic):事务被视为不可分割的最小单元,事务的所有操作要么全部成功,要么全部失败。
- 一致性(Consistency):数据库在事务执行前后都保持一致性状态。在一致性状态下,所有事务对同一个数据的读取结果都是相同的。
- 隔离性(Isolation):一个事务所做的操作在最终提交以前,对其他事务是不可见的。
- 持久性(Durability):一个事务提交后,它对数据的修改会永远保存在数据库中,即使数据库发生故障也不会丢失。
另外,ACID需要注意的几点:
- 只有满足了一致性,事务的执行结果才是正确的。
- 无并发时,事务是串行执行,一定会满足隔离性;所有此时只需满足原子性,就一定能满足一致性;事务的执行结果才是正确的。
- 有并发时,多个事务并行执行,事务不仅要满足原子性,还需要满足隔离性,才能满足一致性,事务的执行结果才能是正确的。
- 事务的持久性是为了应对系统崩溃的情况。
三、并发事务带来问题?
并发时,多个事务经常会操作相同的数据(比如多个用户同时操作一个数据),由此可能会引发以下几个问题:
- 脏读(DIrty read):一个事务T1修改了一个数据,但还未提交;此时另一个事务T2来读取数据,读取到了修改后的数据;结果事务T1撤销了这次修改。那么事务T2读到的就是脏数据了。
- 幻读(Phantom read):在一个事务T1内,多次按条件 查询数据;两次查询之间,另一个并发事务T2插入或删除了几条满足这个条件的数据;那么当事务T1后一次按相同条件再查询时,就会发现多了或少了几条数据。就像出现了幻觉一样,所以叫幻读。
- 不可重复读(Unrepeatable read):在一个事务T1内多次查询同一数据;两次查询之间,并发事务T2修改了这个数据;那么当事务T1再查询该数据时,就会发现两次查询的数据不一样。也就是一个事务内两次查询到的数据不一样,称为不可重复读。
- 丢失修改(Lost to modify):事务T1读取一个数据时,并行事务T2也访问了这个数据;当事务T1修改这个数据后,事务T2也修改了这个数据;那么事务T1修改的事务就被丢失了。所以称为丢失修改。
幻读 和 不可重复读 的区别是:幻读的重点在于数据新增或删除了;不可重复读的重点在于数据被修改了。
四、事务的隔离级别?
SQL标准定义了四个隔离级别:
- 读未提交(READ UNCOMMITTED):最低的隔离级别,事务中的修改,即使还没有提交,其他事务就可以读取到。可能会导致 脏读、不可重复读、幻读。
- 读已提交(READ COMMITTED):事务中的修改,只有提交了之后,其他事务才能读取到。可防止脏读,但是还是可能会发生 不可重复读、幻读。
- 可重复读(REPEATABLE READ):保证同一个事务中多次读取的同一数据的结果是相同的。可防止 脏读、不可重复读,但是还是可能会发生 幻读。
- 可串行化(SERIALIZABLE):最高的隔离级别,完全满足ACID。多个事务依次逐个执行,不能同时执行,这样多个事务之间互不干扰。脏读、幻读、不可重复 都可以防止。
隔离级别 | 脏读 | 不可重复读 | 幻读 |
---|---|---|---|
读未提交 | √ | √ | √ |
读已提交 | × | √ | √ |
可重复读 | × | × | √ |
可串行化 | × | × | × |
MySQL中可用 select @@tx_isolation; 语句查询隔离级别。
MySQL InnoDB存储引擎的默认支持的隔离级别是 可重复读(REPEATABLE-READ)。