事务的特性(ACID)
- 原子性(Atomicity):事务是一个不可分割的工作单位,一个事务中的操作要么全成功,要么全失败
- 一致性(Consistency):事务必须使数据库中的数据从一个合法状态抵达另一个合法状态,即事务按照预期生效则数据应该是预期的状态
- 隔离性(Isolation):多个事务同时并发执行时,每个事务的数据不被其他事务所干扰
- 持久性(Durability):一个事务一旦被提交,那么它对数据的改变就是永久的
事务的隔离级别
一个MYSQL服务器运行时会同时处理多个事务,按正常来讲,根据事务的隔离特性,当一个事务对某一个数据进行访问时,其他的事务应当先排队,但是这样的话效率就会比较低。所以我们希望在保持事务的隔离性的又想尽量提高服务器处理多个事务的性能,只能在二者之间平衡取舍。
数据并发问题
多个事务访问同一数据时,在不保证串行执行的情况下,可能会出现以下数据并发问题:
- 脏写(Dirty Write):事务A修改了事务B已修改但是未提交的数据(之后事务A完成了提交,但是事务B进行了回滚,那么事务A就相当于做了一次临时且无效的更新)
- 脏读(Dirty Read):事务A读取了事务B已修改但是未提交的数据(之后事务A完成了提交,但是事务B进行了回滚,那么事务A就相当于做了一次临时且无效的更新)
- 不可重复读(Non-Repeatable Read):事务A读取了一个数据,之后事务B修改了这个数据,这样就导致事务A两次读取的结果不一致
- 幻读(Phantom Read):事务A查询某一范围的数据,但在事务A未提交前,事务B又往这个范围内插入了数据,事务A再次查询同一范围就会发现数据多了几行
并发问题严重性排序:
脏写>脏读>不可重复读>幻读
MYSQL的事务隔离级别
针对上述的数据并发问题,MySQL提供了四种事务隔离级别:
- 读未提交(READ UNCOMMITTED):在这个级别下,事务可以读取其他事务未提交的数据。虽然性能较好,但会导致脏读问题,即读到了其他事务可能回滚的数据。
- 读提交(READ COMMITTED):在这个级别下,事务只能读取已经提交的数据。脏读问题得到解决,但仍可能出现不可重复读和幻读。
- 可重复读(REPEATABLE READ):在这个级别下,事务内多次读取同一数据时,保证读到的数据一致。不可重复读问题得到解决,但仍可能出现幻读,这是MYSQL的默认隔离级别。
- 串行化(SERIALIZABLE):这是最严格的隔离级别,确保事务之间不会相互干扰。它解决了脏读、不可重复读和幻读问题,但性能较差。
脏写是不可被接受的,四种隔离级别都解决了脏写的问题
隔离级别 | 脏读 | 不可重复读 | 幻读 |
---|---|---|---|
读未提交 | × | × | × |
读已提交 | √ | × | × |
可重复读 | √ | √ | × |
串行化 | √ | √ | √ |
设置隔离级别
#查看隔离级别
select @@transaction_isolation;
#设置全局或者会话级别的隔离级别(READ-UNCOMMITTED、READ-COMMITTED、REPEATABLE-READ、SERIALIZABLE)
set [global|session] TRANSACTION_ISOLATION = '隔离级别';