-
什么是事务
事务就是一系列的DML(增删改)语句的执行要么全部执行成功,要么全部执行失败。一旦执行成功将永久存在。
-
为什么需要事务
例如:张三银行卡的金额为1000元,李四的银行卡金额为1500元。这个时候如果李四向张三转账200元,假设我们把这里的转账行为分成2条sql执行,分别是李四的金额-200元和张三的金额+200元。先执行李四的金额-200元这条sql且成功了,然后再执行张三的金额+200元这条sql但是失败了,这个时候李四的金额变成了1300,但是张三的金额没变化。我们不允许发生这种情况,这个时候我们就要用到事务。
-
事务的四个特性
原子性:要么全部语句执行成功提交,要么全部语句执行失败回滚。不允许部分成功、部分失败的情况。
一致性:事务完成时,数据库的状态必须保持一致性,就是数据库从一个正常的状态转变成另外一个正常的状态。
隔离性:多用户同时操作相同数据时候,会产生多个事务,每一个事务都是独立的,一个事务不会影响另外一个事务。
持久性:当事务一旦提交成功,那么数据将永久存在,即使系统发送故障亦如此。
-
事务的隔离等级
读未提交(Read uncommitted):当一个事务开始对某行数据进行写操作时,其它事务无法同时对该行数据进行写操作,但是能进行读操作。事务间无法同时操作相同数据避免了更新混乱,但是这个时候可以读数据,一旦事务发生回滚就造成了脏读。
例如:account表的balance本来值为500,A事务把balance 修改成300 但未提交事务,B事务这个时候过来读取这个balance值读取到的是300,B事务读取完成之后A事务因为一些异常原因需要回滚,balance就还原到500,这个时候B事务读取到的300就是脏读
读已提交(Read committed):当一个事务对数据进行读操作的时候,另外一个事务能进行写操作,不过写操作进行的时候其它事务不能再进行读写操作。这样就避免了脏读,但是会造成不可重复读
例如:A事务先读取了account的balance的值为500,这个时候其它事务可以进行写操作,B事务就在A事务第一次读完之后把balance改成了300,B事务写操作完成后A事务再读一次balance就会读到balance=300,与第一次读到的balance=500不一致,这样就造成了不可重复读
可重复读(Repeatable read):当一个事务对数据进行读写操作未完成的时候,其它事务不允许对这些数据进行读写操作。这样就避免了脏读和不可重复读但是同时会造成幻读
例如:A事务需要把account表的全部balance修改成0,当A事务在执行的时候B事务向account表插入了一条balance=300的数据,两个事务执行完成之后可能会发现并非所有balance都修改成0,会存在一条balance=300的数据,这就是幻读
可序列化(Serializable):每一个事务必须排队一个一个执行,不允许两个以上事务同时进行。完全避免了任何因为事务并行造成的问题。
安全系数:可序列化 > 可重复度 > 读已提交 > 读未提交
性能系数:读未提交 > 读已提交 > 可重复读 > 可序列号
由此可见隔离等级的安全与性能的关系是成反比的,因为隔离等级的原理就是通过锁或者序列化完成
MySql拥有上面四种隔离等级,默认的隔离等级为可重复度(Repeatable read)。而Orcale只有读已提交与可序列化两种隔离等级,默认隔离等级为读已提交(Read committed)
-
Redo log 与 Undo log
由于存在事务这个概念,那么我们操作数据的时候并非单纯地直接操作磁盘里面的数据,还会涉及到Undo log文件以及Redo log文件,比如我们做一个update操作的时候还会记录Undo log以及Redo log,当我们需要回滚数据的时候,我们需要使用到undo log进行回滚保证原子性,当我们需要持久化数据的时候需要利用Redo log来保证持久性
Redo log原理: 为了保证持久性,每执行完一条sql会记录到Redo log,当数据还在内存的时候就发生宕机,可以通过Redo log来完成持久化,Redo log是在执行sql之后记录并且在事务提交之前持久化到磁盘。
Undo log原理:为了保证原子性,每执行一条sql之前都会记录一条与之相反的sql(例如执行一条inserts语句,Undo log就会记录一条delete语句),当数据需要回滚的时候通过Undo log来完成,Undo log是在执行sql之q前记录。
我们利用最开始张三李四转账那个例子整理一下流程,张三的balance=1000,李四的balance=1500,李四向张三转账200
在学习过程中事务的其中三个特性(原子性,隔离性,持久性)的原理都是有迹可循,唯独一致性始终没有相关的原理信息,并且有诸多歧义。按我的理解,大概一致性的原理就是原子性、隔离性和持久性吧,它们最终的目的就是保持数据库的正常状态