2026/4/17 17:06:28
网站建设
项目流程
全包胶衣网站,东营市做网站优化,wordpress58同城主题,做网站什么域名好??所属专栏#xff1a;MySQL**** ??1. 事务
事务是一组操作的集合#xff0c;它是一个不可分割的工作单位#xff0c;事务会把所有的操作作为一个整体一起向系统提交或撤销操作请求#xff0c;这些操作要么同时成功#xff0c;要么同时失败 例如转账的过程#xff1…??所属专栏MySQL****??1. 事务事务是一组操作的集合它是一个不可分割的工作单位事务会把所有的操作作为一个整体一起向系统提交或撤销操作请求这些操作要么同时成功要么同时失败例如转账的过程张三要给李四转1000元此时需要先查询张三的账户余额接着进行转出然后转入李四的账户但是此时如果程序出现异常就会导致张三的钱没了但是也没有加入到李四的账户上这时就需要用到事务默认MySQL的事务是自动提交的也就是说当执行一条SQL语句MySQL就会立即隐式的提交事务??2. 事务操作一个事务的操作流程包括了开启事务执行事务操作提交事务或回滚事务对于回滚事务来说如果程序在执行过程中出现了错误那么此时就需要执行回滚事务??2.1 查看/设置事务提交方式在刚开始提到过MySQL的事务默认是自动提交的此时把 autocommit 设置为0就改为了手动的select autocommit; set autocommit 0; select * from account; -- 查询张三的账户 select * from account where name 张三; -- 张三账户余额 -1000 update account set money money - 1000 where name 张三; -- 李四账户余额 1000 update account set money money 1000 where name 李四;该为手动之后有与没有设置事务提交所以尽管执行了一些SQL语句但是表中的数据并没有被改变??2.2 开启事务start transaction ;这个和设置autocommit 为0 是一样的效果??2.3 提交事务通过执行 commit 提交事务之后再刷新表格之前的操作就生效了并且一旦提交事务之后就不能再进行回滚事务了??2.4 回滚事务回滚事务是指在事务执行过程中遇到错误、冲突或用户取消操作等情况下撤销已执行但尚未提交的事务中所做的所有修改以恢复数据库到事务开始之前的状态这样做就避免了数据因部分操作成功而部分失败导致的不一致状态。??3. 事务的四大特性事务的四大特性也就是ACID分别为1. 原子性(Atomicity)事务是不可分割的最小操作单元要么全部成功要么全部失败2.一致性(Consistency)事务完成时必须使所有的数据都保持一致状态3.隔离性(Isolation)数据库系统提供的隔离机制保证事务在不受外部并发操作影响的独立环境下运行4.持久性(Durability)事务一旦提交或回滚它对数据库中的数据的改变就是永久的??4. 并发事务问题并发事务问题主要是指多个事务在同时操作一个数据库或是同一张表时可能出现的问题问题描述脏读一个事务读取到另一个事务还没有提交的数据不可重复读一个事务先后读取同一条记录但两次读取的数据不同幻读一个事务按照条件查询数据时没有对应的数据行但是在插入数据时又发现这一行数据已经存在好像出现了一个幻影来解释一下不可重复读例如事务A和事务B同时执行在事务A执行查询操作之后事务B执行更新操作然后事务B提交这时数据库中的内容就被改变了此时再执行事务A中的查询语句由于查询的是相同的对象所以就会出现两次读取的数据不同再来看幻读的例子还是两个事务同时执行此时先执行事务A中的查询语句查询到空的数据之后再执行事务B中的插入语句接着提交事务然后再执行事务A中的插入数据但是 id 1已经在事务B中被插入过了就会发生冲突此时再查询 id 1 就会发现这条数据已经存在了这就是幻读??5. 事务隔离级别隔离级别脏读不可重复读幻读Read uncommitted√√√Read committed×√√Repeatable Read(MySQL默认)××√Serializable×××设置 session 和 global 的区别session会话级session参数仅在当前会话或连接中有效global全局级global参数是全局的意味着改变某个系统变量的值将会对所有会话都产生影响。需要注意的是一旦数据库服务重启除非在配置文件如my.cnf或my.ini中进行了设置否则这些全局变量的改变就会失效。Read uncommitted读未提交这种情况下一个事务可以读取到另一个事务未提交的数据此时脏读不可重复读幻读三个问题都会发生但是此时多个事务并发执行程度是最高的执行速度是最快的Read committed读已提交这种情况下一个事务可以读取到另一个事务已经提交的数据相当于给写操作加锁了此时就可以解决脏读的问题Repeatable Read可重复读这种情况相当于给读操作和写操作都加锁了此时不可重复读的问题也可以解决事务的隔离性进一步提高Serializable串行化此时所有的事务都是在服务器上一个接一个执行的上面所有的并发问题都可以解决事务的隔离性最强但执行速度最慢-- 查看事务的隔离级别 select transaction_isolation; set session transaction isolation level read uncommitted ;接下来同时进行两个事务修改事务 A 的隔离级别为 read uncommitted此时虽然 事务 B 并没有进行提交但是事务 A 读取到了 事务 B 还没有提交的数据就出现了脏读的问题接下来看Read committed首先修改事务 A 的隔离级别为 read committed 然后开启事务 A ,查询当前表中的原始数据然后开启事务 B 执行事务 B 中的语句再次在事务A中查询发现数据并没有被影响当事务B提交之后再在事务A中查询到了修改之后的数据对于这种情况在事务A中一直查询的是同一个表但是由于事务B的提交而查询到不同的结果也就是之前我们提到的不可重复读问题针对这个问题此时再把事务隔离级别修改为Repeatable Read也就是MySQL默认的隔离级别修改事务A的隔离级别为repeatable read并开启事务先查询原始的数据然后执行事务B的语句再次查询这次事务A就不受事务B提交的影响下面来演示一下幻读的问题在MySQL默认的隔离级别下开启事务A查找 id 3的数据并没有找到此时在事务B中插入这条数据由于隔离级别的作用虽然事务B已经提交还是无法找到id 3的数据但是尝试在事务A中插入 id 3的数据却出现了错误这就是幻读此时把隔离级别设置为serializable就能解决这个问题了