如果数据库中同时运行多个事务,则可能会出现问题。
脏读
不要重复(非可重复读取) )。
幻读(phantom read ) )。
为了解决这些问题,有“隔离级别”的概念。 包括以下内容:
阅读未提交的(读未确认)
阅读提交的“已提交”
可重复(repeatable read )。
序列化(serializable )
让我们解决以下三个问题。
肮脏的读法,不可重复的读法,幻读是什么意思?
每个隔离级别意味着什么?
事务隔离是怎么实现的?
事务同步问题
)1)脏读(脏读) () ) ) ) ) )。
示例:
在本示例中,不存在id为1且age为21的记录,并且事务1读取了脏数据。
这是脏领导。 读取了一个事务中另一个事务已修改但未提交的数据。
(2)不可重复(不可重复读取) )。
示例:
无法重复读取意味着在一个事务中读取同一记录两次,但每次读取的结果都不同。
(3)幻读(phantom read ) )。
示例:
幻读是指在一个事务中发生相同的查询条件所得到的结果不同,从而产生了新的记录。
幻读其实是一种不可重复的特殊情况。
事务隔离级别
“未读”(read uncommitted )表示未提交事务时,其他事务中将显示更改。
当您阅读“已提交”(read committed )时,在提交一个事务之前,其他事务将看不到所做的更改。
“可重复读取”(repeatable read )表示在单个事务中看到的数据始终一致。
“序列化”(serializable )会锁定记录。 如果发生锁定冲突,后续事务将在上一事务执行完成之前不会继续。
在下一个场景中,我们将看到隔离级别不同时的结果。
有一个表t,有一个包含记录1的int类型字段c。
事务1
事务2
事务开始; 查询获取值1
启动事务处理
查询获取值1
把一变二
查询得到值V1
提交事务处理
查询得到值V2
提交事务处理
查询得到值V3
按隔离级别列出的值:
隔离级别是未提交的读取
V1=2,此级别上事务2的更改可以由事务1看到。
V2和V3一样是2。
隔离级别是已提交的读取
V1=1,V2=2,在此级别看不到事务2未提交的更改事务1,提交后事务1可见。
V3=2。
隔离级别是可读的
V1=1,V2=1,在此级别上,事务1执行期间出现的值匹配。
V3=2。
隔离级别串行化
事务2已锁定,等待事务1提交。 V1=1,V2=1,V3=2。
实现事务隔离
我们是如何实现不同事务的不同值的呢?
有一个重要概念叫“回滚日志”。
在MySQL中,每个记录都可以在更新时记录回滚操作记录,并通过回滚操作获得以前的某个状态的值。
例如,如果将值从1依次更改为4,则回滚日志将如下所示:
从1改为2
另一个重要概念“视图-读视图”是在事务启动时创建视图并对应于回退日志。
例如,三个事务生成三个视图A B C,与回退日志的对应关系如下:
事务a获取的值始终为1,其他事务也是如此。 新线程将值从4更改为5不会影响其他事务。