标签:不能 特性 手动 最新 根据 后台 shared mysqld png
原子性:一个事务(transaction)中的所有操作,要么全部完成,要么全部不完成,不会结束在中间某个环节。事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。
一致性:在事务开始之前和事务结束以后,数据库的完整性没有被破坏。这表示写入的资料必须完全符合所有的预设规则,这包含资料的精确度、串联性以及后续数据库可以自发性地完成预定的工作。(比如:A向B转账,不可能A扣了钱,B却没有收到)
隔离性:数据库允许多个并发事务同时对其数据进行读写和修改的能力,隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致。事务隔离分为不同级别,包括读未提交(Read uncommitted)、读提交(read committed)、可重复读(repeatable read)和串行化(Serializable)。(比u人:A正在从一张银行卡里面取钱,在A取钱的过程中,B不能向这张银行卡打钱)
持久性:事务处理结束后,对数据的修改就是永久的,即便系统故障也不会丢失。
默认情况下,Mysql的事务是自动提交的,可以使用show variables like ‘autocommit‘;
查看。
也就是说,在没有手动开启(Begin)一个事务的情况下,执行增删改操作都是会自动提交的。
事务的四个隔离级别:
这四种隔离级别分别会造成的后果:
脏读 | 不可重复读 | 幻读 | |
---|---|---|---|
读未提交 | ? | ? | ? |
读已提交 | ? | ? | ? |
可重复读 | ? | ? | ? |
串行化 | ? | ? | ? |
1.可以在my.ini文件中使用transaction-isolation选项来设置服务器的缺省事务隔离级别。
四种级别:
例如:
[mysqld]
transaction-isolation = READ-COMMITTED
2.通过命令动态设置隔离级别
例如:
SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;
1.脏读:(读取未提交数据)
脏读就是指当一个事务正在访问数据,并且对数据进行了修改,而这种修改还没有提交到数据库中,这时,另外一个事务也访问这个数据,然后使用了这个数据。
2.不可重复读:(前后多次读取,数据内容不一致
事务A和事务B,事务B读取了数据,然后事务A对数据进行了修改并提交,事务B再次读取数据,发现数据发生了改变
3.幻读:(前后多次读取,数据行数量发生了变化)
事务B首先根据条件查询得到N条数据,然后事务A改变了这N条数据之外的M条或者增添了M条符合事务A搜索条件的数据,导致事务A再次根据此条件查询发现有了N+M条数据了,就产生了幻读
“不可重复读”关注的重点其实在于更新和删除这两种操作。
比如:事务B开启后,第一次读取到一些数据之后,就对这些数据进行加行锁,导致事务A无法修改(更新或者删除)数据,于是B事务不管怎么读,返回的都是一样的数据,这就实现了“可重复读”这个隔离级别。
可是要注意:“事务A无法修改这些数据(更新或删除)”,不代表事务A不能insert或update没有被事务B加锁的数据并提交。这样一来事务B再次查询时还是可以读取到一条之前没有出现的数据,这就产生了“幻读”。
所以说,行级锁是无法解决幻读问题的。要想解决这个问题就要实现Serializable隔离级别或者加表级锁。
redo log叫做重做日志,是用来实现事务的持久性。该日志文件由两部分组成:重做日志缓冲(redo log buffer)以及重做日志文件(redo log),前者是在内存中,后者在磁盘中。当事务提交之后会把所有修改信息都会存到该日志中。
例如:
start transaction;
select balance from bank where name="zhangsan";
// 生成 重做日志 balance=600
update bank set balance = balance - 400;
// 生成 重做日志 amount=400
update finance set amount = amount + 400;
mysql 为了提升性能不会把每次的修改都实时同步到磁盘,而是会先存到Boffer Pool(缓冲池)里头,把这个当作缓存来用。然后使用后台线程去做缓冲池和磁盘之间的同步。
那么问题来了,如果还没来的同步的时候宕机或断电了怎么办?还没来得及执行上面图中红色的操作。这样会导致丢部分已提交事务的修改信息!
所以引入了redo log来记录已成功提交事务的修改信息,并且会把redo log持久化到磁盘,系统重启之后在读取redo log恢复最新数据。
所以:redo log是用来恢复数据的,用于保障,已提交事务的持久化特性(记录了已经提交的操作)
undo log 叫做回滚日志,用于记录数据被修改前的信息。他正好跟前面所说的重做日志所记录的相反,重做日志记录数据被修改后的信息。undo log主要记录的是数据的逻辑变化,为了在发生错误时回滚之前的操作,需要将之前的操作都记录下来,然后在发生错误时才可以回滚。
undo log 的作用是什么?
undo log 记录事务修改之前版本的数据信息,因此假如由于系统错误或者rollback操作而回滚的话可以根据undo log的信息来进行回滚到没被修改前的状态
所以:undo log是用来回滚数据的用于保障,未提交事务的原子性
当有多个请求来读取表中的数据时可以不采取任何操作,但是多个请求里有读请求,又有修改请求时必须有一种措施来进行并发控制。不然很有可能会造成不一致。
读写锁
解决上述问题很简单,只需用两种锁的组合来对读写请求进行控制即可,这两种锁被称为:
InnoDB的MVCC,是通过在每行记录后面保存两个隐藏的列来实现的,这两个列,分别保存了这个行的创建时间,一个保存的是行的删除时间。这里存储的并不是实际的时间值,而是系统版本号(可以理解为事务的ID),没开始一个新的事务,系统版本号就会自动递增,事务开始时刻的系统版本号会作为事务的ID.
标签:不能 特性 手动 最新 根据 后台 shared mysqld png
原文地址:https://www.cnblogs.com/cky-2907183182/p/12628893.html