MYSQL系列(五)事务/事务日志/事务隔离级别

mysql事务

事务就是一组原子性的SQL查询,或者说一个独立的工作单元。如果数据库引擎能够成功地对数据库 应用该组查询的全部语句,那么执行该组查询。如果其中有任何一条语句应为崩溃或其他原因无法执行, 那么所有的语句都不会执行。也就是说,事务内的语句,要么全部执行成功,要么全部执行失败。良好的 事务必须满足四大特性。

事务的四大特性

原子性(Atomicity): 事务是一个原子操作单元,其对数据的修改,要么全部执行,要么全部不执行。

一致性(Consistency) : 在事务开始和完成时,数据都必须保持一致状态。这意味着所有相关的数据规则都必须应用于事务的修改,以保持数据的完整性;事务结束时,所有的内部数据结构也都必须是正确的。

隔离性(Isolation) : 数据库系统提供一定的隔离机制(MVCC机制),保证事务在不受外部并发操作影响的 "独立"环境执行。这意味着事务处理过程中的中间状态对外部是可见的,反之亦然。

持久性(Durability): 事务完成之后,它对数据的修改是永久性的,即使出现系统故障也能够保持。

并发事务带来的问题

脏读

一个事务正在对一条记录做修改,在这个事务完成并提交前,这条记录的数据就处于不一致状态;这时,另一个事务也来读取同一条记录,如果不加控制,第二个事务读取了这些"脏"数据,并据此作进一步的处理,就会产生未提交的数据依赖关系,这种现象被形象的叫做 “脏读”。

一句话:事务A读取到了事务B已修改但尚未提交的数据,还在这个数据基础上做了操作。此时,如果事务B回滚,A读取的数据无效,不符合一致性要求

不可重复度

一个事务在读取某些数据后的某个时间,再次读取以前的数据,却发现其读出的数据已经发生了改变、或某些记录已经被删除了!这种现象就叫做"不可重复度"。

一句话:在事务A读取到了事务B已经提交的修改数据,不符合隔离性

幻读

一个事务按相同的查询条件重新读取以前检索过的数据,却发现其他事务插入了满足其查询条件的数据,这种现象被称为"幻读"。

一句话:事务A读取到了事务B提交的新增数据,不符合隔离性

幻读和脏读有点类似
脏读是事务B里面修改了数据;
幻读是事务B里面新增了数据;

事务日志

事务日志可以帮助提高事务的效率。使用事务日志,存储引擎在修改表的数据时只需要修改其内存拷贝,再把该修改行为记录到持久在硬盘上的事务日志中,而不用每次都将修改的数据本身持久到磁盘。事务日志采用的是追加的方式,因此写日志的操作是磁盘上一小块区域内的顺序I/O,而不像随机I/O需要在磁盘的多个地方移动磁头,所以采用事务日志的方式相对来说要快得多。事务日志持久以后,内存中被修改的数据在后台可以慢慢地刷回到磁盘。目前大多数存储引擎都是这样实现的,我们通常称之为预写式日志(Write-Ahead Logging),修改数据需要写两次磁盘。
如果数据的修改已经记录到事务日志并持久化,但数据本身还没有写回磁盘,此时系统崩溃,存储引擎在重启时能够自动恢复这部分修改的数据。

MySQL Innodb中跟数据持久性、一致性有关的日志,有以下几种:

Bin Log:是mysql服务层产生的日志,常用来进行数据恢复、数据库复制,常见的mysql主从架构,就是采用slave同步master的binlog实现的。

Redo Log:记录了数据操作在物理层面的修改,mysql中使用了大量缓存,修改操作时会直接修改内存,而不是立刻修改磁盘,事务进行中时会不断的产生redo log,在事务提交时进行一次flush操作,保存到磁盘中。当数据库或主机失效重启时,会根据redo log进行数据的恢复,如果redo log中有事务提交,则进行事务提交修改数据。

Undo Log: 除了记录redo log外,当进行数据修改时还会记录undo log,undo log用于数据的撤回操作,它记录了修改的反向操作,比如,插入对应删除,修改对应修改为原来的数据,通过undo log可以实现事务回滚,并且可以根据undo log回溯到某个特定的版本的数据,实现MVCC

事务隔离级别

隔离级别 脏读 不可重复度 幻读
读未提交(READ-UNCOMMITTED) 可能 可能 可能
读已提交(READ-COMMITTED) 不可能 可能 可能
可重复度(REPEATABLE-READ) 不可能 不可能 可能
可串行化(SENALIZABLE) 不可能 不可能 不可能

数据库的事务隔离级别越严格,并发副作用越小,但付出的代价也就越大。因为事务隔离实质上就是使事务在一定程度上"串行化"进行,这显然与"并发"是矛盾的。

查看当前数据库的事务隔离级别: show variables like ‘tx_isolation’;
设置事务隔离级别: set tx_isolation = ‘REPEATABLE-READ’;
mysql的默认隔离级别: 可重复读

发布了12 篇原创文章 · 获赞 0 · 访问量 339

猜你喜欢

转载自blog.csdn.net/fd135/article/details/104320717