业务系统在运行时,很多线程经常同时操作数据库,MySQL也需要多线程处理多个请求。 那么,每个事务中的多个SQL语句是如何执行的呢? 基本上是从磁盘将数据页面加载到Buffer Pool的缓存页面,更新Buffer Pool的缓存页面,同时记录重做日志和还原日志。
多个线程同时运行时,会出现一些问题。
如果同时执行多个事务,则缓存页中同一行的数据可能会更新。 这个冲突怎么解决?
如果一个事务更新一行的数据,另一个事务查询该行的数据,该冲突如何解决?
接下来要说明的内容主要包括多事务并发问题、MySQL的事务隔离级别、MVCC多版本控制和锁定。
肮脏的读音
如果事务1读取由事务2更新的数据,然后事务2回滚该操作,则事务1读取的数据将是脏数据。
例如:
神勇招牌的工资是8000,现在领导要给他涨10000工资。
事务1虽然把他的工资改为10000,但事务还没有提交。
我在读事务2神勇招牌的工资。 独特的是10000。
事务1这个时候回滚,神勇招牌的工资又涨了8000。
事务2读取神勇招牌的工资10000作为脏数据,事务2进行了一次脏领先。
不可重复
由于事务1多次读取相同的数据,并且事务2在事务1多次读取的同时更新并提交数据,所以如果事务1多次读取相同的数据,则结果不匹配。
例如:
事务1、神勇招牌上读取的工资8000。
事务2、神勇招牌工资改为10000,提交事务。
事务1、再次读取神勇招牌的工资。 这时的工资是10000。
在一个事务中前后两次读取同一数据的结果不同的是,不能重复。
幻读
一个事务在同一SQL中多次查询,每次查询都发现了以前从未见过的数据。
例如,现在公司工资8000人的有10人。
事务一、读取所有工资8000人10人。
事务2、插入工资10000的记录。
如果重新读取事务1薪8000的人,就会变成11人。
这时,事务1中出现了类似幻觉的相同的SQL查询句,第一次检测出10人,第二次检测出11人。
不可重读的和幻读容易混淆,不可重读的侧重于修改,幻读侧重于添加或删除。 要解决不可重复的问题,只需锁定满足条件的行,而要解决幻像读取问题,则必须锁定表。
脏读取、不可重复读取和幻像读取可以同时运行数据库,为每个线程打开事务,并为每个事务执行crud操作。
如果数据库同时执行多个事务,并且多个事务同时crud缓存页中的相同数据,则可能会出现脏读取、不可重复读取和幻像读取问题。
因此,这些问题的本质是数据库的多事务并发问题,为了解决这些问题,数据库设计了事务分离级别、MVCC多版本控制和锁定机制。
事务隔离级别
SQL标准定义了四个事务隔离级别。 也就是说,当事务同时执行时,它们如何相互隔离。 MySQL缺省为可重复读取(RR )。
隔离级别不同可以避免事务的并发性问题。
读取未确认(ru )可能会发生脏读取、不可重复读取和幻像读取。
读-已提交(RC )不发生脏读,但不发生重复读取、幻读
也就是说,事务所没有提交的情况下修改的值,你不能读。 但是,事务被提交后,你的事务可以读,所以可能读了好几次的值会不一样。
repeatable-read(RR )是MySQL的缺省事务隔离级别,为解决脏读取、不可重复读取和幻像读取问题进行了许多复杂的工作。 在一般的生成环境中使用这个隔离级别就可以了。
序列化,因为事务是串行执行的,根本不会同时执行,所以不存在脏读、不可重复读、幻读之类的问题。 但是缺点也很明显,合并太差了。 一般生产环境中也不使用
MySQL事务隔离级别| 《Linux就该这么学》 (Linux专业版.com) ) ) ) ) ) ) ) ) ) ) ) )。