事务操作
• 查看/设置事务提交方式
-- autocommit的值默认为1,即自动提交,设置成0为手动提交
select @@ autocommit;
set @@ autocommit=0;
• 提交事务
commit;
• 回滚事务
rollback;
• 开启事务
-- 开启事务
start transaction 或 begin;
事务操作代码演示
-- 事务操作
-- 数据准备
create table account(
id int auto_increment primary key comment '主键ID',
name varchar(10) comment '姓名',
money int comment '余额'
)comment '账户表';
insert into account(id, name, money) VALUES (null,'张三',2000),(null,'李四',2000);
-- 恢复数据
update account set money = 2000 where name = '张三' or name = '李四';
select @@autocommit;
set @@autocommit = 0; -- 设置手动提交
-- 转账操作 (张三给李四转账1000)
-- 1.查询张三账户余额
select * from account where name='张三';
-- 2.将张三账户余额-1000
update account set money = money - 1000 where name = '张三';
-- 程序执行错误 ...
-- 3.将李四账户余额+1000
update account set money = money + 1000 where name = '李四';
-- 提交事务
commit ;
-- 回滚事务
rollback ;
-- 方式二
-- 转账操作 (张三给李四转账1000)
start transaction ;
-- 1.查询张三账户余额
select * from account where name='张三';
-- 2.将张三账户余额-1000
update account set money = money - 1000 where name = '张三';
-- 程序执行错误 ...
-- 3.将李四账户余额+1000
update account set money = money + 1000 where name = '李四';
-- 提交事务
commit ;
-- 回滚事务
rollback ;
这里给大家讲一下细节,接下来我们来看这段代码
代码正常选中执行,如果 autocommit 的值为1,就是自动提交,即张三的余额减1000,李四的余额加1000,那我们来看一下代码运行后的结果!
你会发现张三的余额确实是减了1000,李四的余额加了1000。那接下来我们在看这段代码
执行这段代码之前我们先把数据恢复,数据恢复的代码如下
-- 恢复数据
update account set money = 2000 where name = '张三' or name = '李四';
好我们执行这段代码
很明显这段代码有错误,运行肯定也有错误的,那接下来我们去看一下表里面的数据。
选中代码运行之后,你会发生张三的余额减了1000,李四的余额却没有变化,真是奇了怪了,那我们思考一下,张三的钱去哪了?我们又应该怎么去解决这个问题?
其实解决这个问题也很简单,要利用到提交事务和回滚事务,且要设置 autocommit 的值为0,就是手动提交
我们先把数据恢复,再设置 autocommit 的值为0
接着我们再次运行刚刚那段有错误的代码
运行结果肯定会报错,我们直接去看表里面的数据
我们发现,和之前的结果不一样了,张三的余额和李四的余额没有发生变化,为什么?很简单,因为你设置 autocommit 的值为0 即是手动提交事务。其实你无论执行正确的代码还是有错误的代码,你没有手动提交事务,表里面的数据就不会有任何变化。
当运行结果系统给你报错了,就证明代码有错误的地方,这个时候也不要慌,回滚事务就好
-- 回滚事务
rollback;
当运行结果没有任何问题,我们就手动提交事务,就避免张三的余额减1000,李四的余额却没有任何变化的那种问题了
-- 提交事务
commit;
事务四大特征
• 原子性 :事务是不可分割的最小操作单元,要么全部成功,要么全部失败• 一致性 : 事务完成时,必须使所有的数据都保持一致状态
• 隔离性 : 数据库系统提供的隔离机制,保证事务在不受外部并发操作影响的独立环境下运行
• 持久性 : 事务一旦提交或回滚,它对数据库中的数据的改变就是永久的
并发事务问题
问题 | 描述 |
脏读 | 一个事务读到另一个事务还没有提交的数据 |
不可重复读 | 一个事务先后读取同一条记录,当两次读取的数据不同,称之为不可重复读 |
幻读 | 一个事务按照条件查询数据时,没有对应的数据行,但在插入数据时,又发现这行数据已经存在,好像出现了幻影 |
事务隔离级别
事务隔离级别就是为了防止并发事务问题的发生
隔离级别 | 脏读 | 不可重复读 | 幻读 |
read uncommitted | √ | √ | √ |
read committed | × | √ | √ |
repeatable read(默认) | × | × | √ |
serializable | × | × | × |
查看事务隔离级别
-- 查看事务隔离级别
select @@transaction_isolation;
设置事务隔离级别
-- 设置事务隔离级别
-- set session 会话级别 针对当前客户端窗口有效
-- set global 针对所有客服端的会话窗口有效
set [session|global] transaction isolation level{
read uncommitted |
read committed |
repeatable read |
serializable
};
注意: 事务隔离级别越高,数据越安全,但是性能越低
就像 serializable 的级别很高,数据很安全,都能避免脏读,不可重复读,幻读的问题,但缺点就是性能低
简单总结一下
1.事务简介
事务是一组操作的集合,这组操作,要么全部指行成功,要么全部执行失败2.事务操作
start transaction; -- 开启事务
commit / rollback; -- 提交/回滚事务3.事务四大特性
原子性(Atomicity)
一致性(Consistency)
隔离性(lsolation)
持久性(Durability)4.并发事务问题
脏读、不可重复读、幻读5.事务隔离级别
read uncommitted
read committed
repeatable read
serializable
小编想说的话
写的不好,仅供参考,如有不足的地方,请各位大佬矫正。另外小编想说的是,制作文章属实不易,每一篇文章都很花时间,很花心思去写,有时候一遍文章写了一周都没有写完哈哈,为了文章写的通俗易懂,小编在这方面也下了不少心思。写文章的目的一是提供给有需要的人和不懂的人学习,二是自己复习巩固。另外小编会抽时间写一遍MySQL基础篇的大总结,希望能对刚接触MySQL的学习者有所帮助。
最后都看到这里了,觉得对你有所帮助的话,点赞关注收藏支持一下小编吧。呜呜呜~,你们关注小编,小编看到会回关的,偷偷告诉你哦,在评论区随便评论一句话,原力积分都能+1哦。
点个赞再走吧