MySQL数据库事务完整详解
事务是数据库保障数据一致性、处理并发操作的核心机制拥有 ACID 四大特性。本文详细介绍事务基础语法、保存点机制分析并发引发的脏读、不可重复读、幻读问题讲解MySQL四大隔离级别文章目录什么是事务ACID特性原子性 Atomicity一致性 Consistency隔离性 Isolation持久性 Durability事务语法保存点事务的隔离性详解事物的隔离级别读未提交Read Uncommitted读已提交Read Committed可重复读Repeatable Read串行化Serializable设置事务隔离级别什么是事务事务是一个不可分割的工作单位原子的是用户定义的数据库操作序列也就是将多个操作打包成一个整体这些操作要么都做要么都不做不会出现其他情况经典场景转账、抢票、选课等等针对转账这个场景来说A给B转200元这一过程A的余额要减200元B的余额要加200元这两个操作同时进行并且不受其他操作的影响。这时就需要使用事务将这两个操作当成一个整体要么转账成功要么转账失败金额和转账前保持一致不会出现只扣A余额、不增加B余额或是只增加B余额、不扣除A余额等这类数据不一致的异常情况。事务是恢复和并发控制的基本单位。并发是指多个事件在同一时间段内执行宏观上看是多个事件同时执行对数据库进行操作时结果超出预期的原因就是因为并发ACID特性事物的ACID分别指原子性Atomicity、一致性Consistency、隔离性Isolation、持久性Durability原子性 Atomicity原子性是指一个事务中的所有操作当成一个不可分割的整体使这些操作要么全部执行成功要么全部执行失败并将执行失败的操作还原回初始状态。这里需要注意的是对于更新操作来说在执行操作前会先打印初始数据的日志然后再执行操作。之所以事务执行失败时数据看起来没发生任何改动、操作看起来没执行是因为会将已经执行的操作根据日志将其还原回初始状态而这个还原数据的过程叫回滚rollback当事务执行成功或者执行完回滚操作后这就标志着这个事务的完成和结束而在事务完成后这个事务所记录的日志就失效了系统会自动清理该日志而我们之前对表进行的增删改查操作也是依托了事务机制MySQL在执行SQL语句前会默认开启事务执行成功后会默认提交事务如果执行失败会进行回滚并打印报错信息一致性 Consistency一致性是指事务的执行结果必须是从一个一致性状态变为另一个一致性状态隔离性 Isolation隔离性是指事务内部的操作与其他事务是隔离的、互不干涉的不会因为持久性 Durability持久性也叫永久性在事务完成后其对数据的修改是永久性的并写入对应的表中不会因为其他情况而造成数据的丢失事务语法先简单了解一下事务语法后续会详细说明-- 开启事务starttransaction;begin;-- 提交事务commit;-- 回滚rollback;其中commit 和rollback都表示这个事务的结束标志例如begin;#1insertintostudentvalues(1,张三,男);insertintostudentvalues(2,李四,女);#2rollback;#3insertintostudentvalues(3,王五,男);#4insertintostudentvalues(4,赵六,女);commit;#5执行1-2之间的语句查询student表执行3对该事务中已执行的所有SQL语句进行回滚查询得此时这个事务结束再来重新开启一个事务执行1-2、4-5查询得执行了commit表示这个事务结束此时执行回滚操作无效表没有发生任何改变保存点事务的局部回滚保存点可以指定部分SQL语句的回滚将保存点之后、当前执行位置之前的SQL语句进行回滚savepoint保存点名称;#创建保存点rollbackto保存点名称;#从指定保存点开始回滚其中执行完’rollback to 保存点名称;’ 后该事务不会结束只有在’rollback’或者’commit’执行完毕后才表示整个事务完成而此时该事务的所有保存点失效例如begin;#1insertintostudentvalues(1,张三,男);insertintostudentvalues(2,李四,女);savepointa;insertintostudentvalues(3,王五,男);savepointb;insertintostudentvalues(4,赵六,女);#2rollbacktoa;#3rollbacktob;#4rollback;#5执行1-2查询得执行3此时会将 a保存点 至 2之间的SQL语句进行回滚查询得此时事务还没结束执行5会将该事务已执行的所有SQL语句进行回滚此时该事务结束事务的隔离性详解在前面我们提到事务的隔离性是指事务内部的操作与其他事务相隔离互不干涉事务是恢复和并发控制的基本单位。并发是指多个事件在同一时间段内执行宏观上看是多个事件同时执行所以并发性越好、执行效率越高并发操作会出现脏读、不可重复读、幻读问题而事务的隔离级别的设置可以解决对应的问题事物的隔离级别在MySQL的InnoDB引擎中事务的隔离级别可分为读未提交低、读已提交、可重复读、串行化高。MySQL的InnoDB引擎默认隔离级别是可重复读隔离级别越高数据的完整性越高并发性越差效率越低隔离级别越低数据的完整性越低并发性越好效率越高完整性包括数据的正确性和数据的相容性读未提交Read Uncommitted字面意思理解就是允许读取未提交的数据这一隔离级别是出现脏读的主要原因我们先谈谈什么是脏读脏读就是读取到的数据是无效的、不正确的。常见的是B事务读取了A事务中修改了但未提交的数据然后A事务将该数据进行回滚了此时B事务中拿到的数据就是脏数据这个读取过程就是脏读读未提交这一隔离级别没有对这两个事务的执行顺序进行干预读已提交Read Committed读已提交这一隔离级别对事务的执行顺序进行了一定干预。它规定B事务只能读取A事务执行完成后的数据。所以读已提交解决了脏读问题但是又出现新的问题了事务C中先后读取D的值发现前后两次读取的值不一致这就是不可重复读问题可重复读Repeatable Read可重复读隔离级别可以解决不可重复读问题它涉及到了快照机制就是事务在执行select操作时搞了份快照可以理解为复制了一份后续读取对应数据时不会读取最新修改的而是读取快照里面保存的数据这个隔离级别已经能处理一些幻读问题但在特殊情况下仍然处理不了串行化Serializable可重复读这一隔离级别解决了同个事务中先后读取的值不一致的情况那么串行化解决的是同个事务中先后读取的数据集不同的情况可以从根本上解决的是幻读问题幻读串行化就是使事务进行串行操作就是使多个事务依次按照顺序执行只有在执行完当前事务后才能开启下个事务且同一时间只能执行一个事务设置事务隔离级别全局级别语法数据库服务器重启后失效-- 语法1setglobaltransactionisolationlevel隔离级别;-- 语法2setglobal.tx_isolation隔离级别;事务隔离级别永久生效要修改.ini文件里面的配置文件路径通常在‘C:\ProgramData\MySQL\MySQL Server 8.0\my.ini’