Mysql-事务

一、事务的基本介绍

              概念:一个包含多个步骤的操作,被事务管理,要么同时成功,要么同时失败。

              基本操作:

                      ①开启事务:start transaction;

                      ②回滚:rollback;

                      ③提交:commit;

-- 开启事务
start transaction;


-- 执行事务中的操作
update scm_sales_order set order_people_num=3 where id='704cb0dc-f12b-4e54-b4d1-fcd3490dd4a6';

update scm_sales_order set order_people=1 where id='704cb0dc-f12b-4e54-b4d1-fcd3490dd4a6';


-- 如果事务成功则提交
COMMIT;


-- 如果事务操作有一步失败则回滚到开启事务语句前状态
ROLLBACK;

              事务的提交特别注意事项:

                    ①Mysql中事务是默认自动提交的,即@@autocommit=1;

                    ②当使用start transaction命令时,则需要手动提交,即执行commit命令;

                    查询提交设置的语句:

                            ①select @@autocommit;      -- 1:自动提交事务;0:手动提交事务

                            ②set @@autocommit=0;       -- 设置事务提交方式语句 

二、事务的四大特征

              原子性:事务是不可分割的最小单位,要么同时成功,要么同时失败;

              持久性:一旦事务提交或者回滚后,数据库就会发生持久性的数据变化;

              隔离性:多个事务之间相互独立;

              一致性:事务操作前后,数据总量不变;

三、事务的隔离级别

              概念:多个事务之间相互隔离,相互独立,如果多个事务操作到同一批数据,可能会出现问题,mysql中可以通过设置事务的隔离级别来解决这些出现的问题。

              可能会出现的问题主要有以下:

                     ①脏读:一个事务中的操作读取到其他事务没有提交的数据;

-- 前提条件:打开两个查询窗口,查询窗口1,此时数据库的隔离级别为read uncommited:读未提交

-- 步骤1:窗口1开启事务
start transaction;

-- 步骤2:打开查询窗口2,窗口2开启事务
start transaction;

-- 步骤3:去窗口1中执行的操作,但是不提交事务,原user表大鸭梨同学的年龄为10
update user set age=age+20 where name='大鸭梨';

-- 步骤4:去窗口2查询user表,发现查询结果为30
select age from user where name='大鸭梨';

-- 结论:在窗口2中查询到了窗口1事务中sql的未提交内容,出现了脏读现象;


-- 解决办法:将本实验前提条件修改为使用隔离级别read committed,则相同的实验步骤下,步骤4读取到的内容为10,可以解决脏读问题。


                     ②不可重复读:一个事务中两次读取到的数据不一样;

-- 前提条件:打开两个查询窗口,查询窗口1,此时数据库的隔离级别为read commited:读已提交

-- 步骤1:窗口1开启事务
start transaction;

-- 步骤2:打开查询窗口2,窗口2开启事务
start transaction;

-- 步骤3:去窗口1中执行的操作,但是不提交事务,原user表大鸭梨同学的年龄为10
update user set age=age+20 where name='大鸭梨';

-- 步骤4:去窗口2查询user表,发现查询结果为10
select age from user where name='大鸭梨';

-- 步骤5:去窗口1执行提交事务
commit;

-- 步骤6:去窗口2查询user表,发现查询结果变更为30
select age from user where name='大鸭梨';

-- 结论:对比步骤4和步骤6的查询结果,可以知道对于窗口2事务,2次读取到的数据结果不一致,则发生了不可重复读取(虚读)问题;

-- 解决方法:相同实验步骤下,将前提条件修改为repeatable read,则步骤6中查询结果和步骤4中查询结果保持一致为10,则解决了虚读问题。当窗口2中的事务commit或者rollback后,再次查询才会查询到变更后的结果为30;

                     ③幻读:一个事务操作全表的数据(DML),另外一个事务新增了一条数据,则第一个事务读取不到新增的记录;

mysql无法演示。

              事务的隔离级别:

                     ①read uncommited:读未提交, 可能出现问题:脏读、不可重复读、幻读;                           

                     ②read committed:读已提交,可能出现问题:不可重复读、幻读;                                      

                     ③repeatable read(mysql默认):可重复读,可能出现问题:幻读;                 

                     ④serializable:串行化,可解决所有问题;

-- 前提条件:打开两个查询窗口,查询窗口1,此时数据库的隔离级别为serializable:锁

-- 步骤1:窗口1开启事务
start transaction;

-- 步骤2:打开查询窗口2,窗口2开启事务
start transaction;

-- 步骤3:去窗口1中执行的操作,但是不提交事务,原user表大鸭梨同学的年龄为10
update user set age=age+20 where name='大鸭梨';

-- 步骤4:去窗口2查询user表,查询等待中没有结果
select age from user where name='大鸭梨';

-- 步骤5:去窗口1执行提交事务
commit;

-- 步骤6:去窗口2查看sql查询情况,查询出结果为30


-- 结论:窗口1中的事务执行时,进行了锁表,导致窗口2中事务无法查询user表,当窗口1事务执行完成后,窗口2事务才开始执行。

                操作事务隔离级别设置语句如下:
 

 -- 查询隔离级别命令
 select @@tx_isolation;
 
 -- 更改事务隔离级别命令
 set global transaction isolation level READ COMMITTED;

                  

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值