1、mysql事务

—mysql中,事务其实是一个最小的不可分割的工作单元。事务能够保证一个业务的完整性,例如:银行存款:

a  - >    -100

>update user set money = money -100 where name ="a";

b - >    +100

>update user set money = money +100 where name ="b";

—实际程序中,如果一条语句执行成功了,而另一条语句执行失败,那么麻烦就大了……

>update user set money = money -100 where name ="a";

>update user set money = money +100 where name ="b";

多条sql语句有要求要么就同时成功,要么就同时失败

2、mysql中如何控制事务?

——查看事务状态(开启还是关闭)

>select @@autocommit;

 

上图‘1’表示mysql 默认是开启事务的(自动提交)

——默认事务开启是什么?

当我们在执行sql语句时,效果会立即体现出来,且不能回滚(回滚后面会讲到)

——下面用一个案例来解释mysql事务:

(1)创建新的数据库名为bank

>create database bank;

(2)在bank数据库中创建新的表名为user

> create table user(

-> id int primary key,

-> name varchar(20),

-> money int);

(3)往user表中添加数据

> insert into user values(1,'a',1000);

(4)查看是否添加成功

>select * from user;

 

(5)回滚(就是撤销sql语句执行的效果)

>rollback;

 

(6)验证sql的语句执行的效果是否撤销

>select * from user;

 

(7)如果想要让回滚有效的话需要关闭事务(关闭mysql的自动提交)

>set @@autocommit=0;

>select @@autocommit;

 

验证回滚:

<a>再插入一条数据

>insert into user values(2,'b',1000);

<b>查看此时的user表

>select * from user;

 

【注】上述的表其实是虚拟的如果现在回滚就可以实现撤销

<c>回滚

>rollback;

<d>查看

>select * from user;

 

<e>重复上述操作

 

<f>由于关闭了自动提交功能,现在手动提交

>commit;

<g>再回滚查看表(显然回滚失效了)

 

【总结】

事务:

——自动提交:@@autocommit=1;

——手动提交:commit;

——回滚:rollback;

转账:

>update user set money = money -100 where name ="a";

>update user set money = money +100 where name ="b";

如果转账失败(同时失败)

可以用回滚实现撤销

>rollback;

——实现:

 

 

(8)小结

——手动开启一个事务的方式:(在这里说一下不知道是不是版本的问题我的电脑上试过了 <2>begin;与 <3>start transaction;是改不了的建议使用第一个,如果您跟我一样,后边关于设置手动事务的都用第一个方法)

<1>set @@autocommit =0;

<2>begin;

<3>start transaction;

具体验证可以参照(7)的流程哦

——关闭手动开启恢复自动开启

>set @@autocommit =1;

——查看事务的状态

>select @@autocommit;

——回滚

>rollback;

——提交

>commit;

【总结】

综上:我们学到了,事务是以两种方式存在的:一是手动开启事务,二是默认(自动)开启事务

手动开启事务给我们提供了一个修改的机会,如果操作失败的话可以通过回滚,实现修改,如果操作成功可以手动提交(commit)增加数据的安全性哦

3、事务的四大特征

A    原子性:事务是最小的单位,不可以再进行分割了

C    一致性:事务要求同一事务中的sql语句,必须保证同时成功或者同时失败

I     隔离性:事务1与事务2之间具有隔离性(后面详解)

D    持久性:事务一旦结束(commit),就不可以返回(rollback)

4、事务的隔离性

(1)read uncommitted        读未提交的

(2)read committed            读已提交的

(3)repeatable  read           可以重复读

(4)serializable                    串行化


(1)read uncommitted        读未提交的

【定义】现有事务a和事务b,a事务对数据进行操作,在操作过程中,事务没有被提交,但是b可以看见a操作的结果

<a>在bank中的表user中插入两条数据

>insert into user values(3,'小明',1000);

>insert into user values(4,'淘宝店',1000);


【拓展】

——如何查看数据库的隔离级别

mysql 8.0

<a>系统级别的

> select @@global.transaction_isolation;(如下图:mysql默认的系统隔离级别)

 

<b>会话级别的

> select @@transaction_isolation;

mysql 5.x

<a>系统级别的

> select @@global.tx_isolation;

<b>会话级别的

> select @@tx_isolation;

——如何修改数据库的隔离级别?

>set global transaction isolation level read uncommitted;

查看修改结果:

 

模拟脏读:上述已经添加了小明和淘宝店两个用户

小明现要在淘宝买一双800元的鞋子,开始付钱

小明    ——>成都

淘宝    ——>广州

<a>开启手动开启事务

>set autocmmit =0;

<b>转账

>update user set money = money -800 where name ='小明';

>update user set money = money +800 where name ='淘宝店';

<c>小明查看转账记录,并通知发货

 

<d>淘宝店在广州查账(这里模拟的话可以再打开一个终端操作),到账欣喜(准备晚上请女朋友吃大餐),并发货

 

<e>晚上吃饭结账1800,刷卡显示余额不足(先自己想想为什么哦),气急败坏,再次查账:

 

<f>原来小明是个黑客,利用所学知识,回滚了(查账,欣喜又赚了一笔)

 

【总结】在事务隔离性为  read uncommitted  ( 读未提交的)情况下:

两个不同的地方,都在进行操作,如果事务a开启之后,他的数据可以被其他事务读取到

这样就会像上述实例那样,出现脏读;

脏读:一个事务读到了另外一个事务并没有提交的数据,这就叫做脏读

当然实际开发中是不允许的

(2)read committed            读已提交的

——修改事务隔离性

>set global transaction isolation level read committed;

实例:bank数据库,user表

<a>小张:银行会计    需要报表:

>begin;

> select * from user;

 

<b>小张出去上厕所去了,这时小王又在另一台电脑上开了一个账户

> insert into user values(5,'c',100);

<c>小张这时回来了,计算money平均值

>select avg(money) from user;

 

<d>很纳闷,怎么变少了,看着报表陷入沉思(这个实例虽然有点脑残,主要是理解这个事务隔离性哈)

【总结】在事务隔离性为    read committed  (读已提交的)

虽然可以读到另外一个数据提交的数据(不会出现脏读),但还是会出现问题就是

读取同一个表,发现前后数据不一致,

不可重复读现象: read committed

(3)repeatable read       可以重复读

先对之前的隔离性做更改

>set global transaction isolation level repeatable read;

——那么在这种情况下又会发生什么事情呢?

【实例】

张全蛋—北京(是repeatable read    事务隔离的情况下)

<a>开启手动事务服务

>set autocommit =0;

<b>开通一个账户

>insert into user values(6,'d',1000);

<d>查看

>select * from user;

 

王尼玛—上海(默认事务隔离性的情况下)

<a>开启手动事务服务

>set autocommit =0;

<b>也想开通账户,开通前先查看(注意模拟的话可以再打开一个终端)

>select * from user;

<c>因其只开通了5个,于是想要继续开通6

> insert into user values(6,'d',1000);

结果:

 

<d>很奇怪,为啥不行的,明明没有6,陷入沉思

<e>试试创建id=7,很成功

>insert into user values(7,'d',100);

<f>查看

>select * from user;

 

<g>很奇怪,创建id=6为啥就是不行呢,陷入沉思……(我告诉你这叫做幻读,嘿嘿)

【总结】这种现象叫做幻读

幻读:事务a和事务b同时操作一样表,事务a提交数据也不会被事务b读到,就会造成幻读

(4)serializable                    串行化

——先更改事务隔离性

>set global transaction isolation level serializable;

【实例】

——张全蛋—成都

>set autocommit =0;

开户并提交

>insert into user values(7,'赵铁柱',1000);

>commit;

——王尼玛—北京

>set autocommit =0;

查看表,看到了赵铁柱

>select * from user;

 

——张全蛋—成都

又开了一个户

>insert into user values(8,'王小花',1000);

但是进入等待状态了,卡住了

这时——王尼玛—北京上述有说到正在看表,此时马上提交:commit,张全蛋那立刻就不卡了

这就是串行化

【总结】

当user表被另外一个事务操作的时候,其他事务里面的写操作,是不可以进行的

进入排队状态(串行化),直到王尼玛不进行事务操作了(输入commit结束事务之后),张全蛋这个写入操作才会执行(在没有超时的情况下)

——串行化带来的问题:性能太差

read uncommitted  > read committed   > repeatable  read   >  serializable

即隔离级别越高,性能越差

mysql默认的级别是    repeatable  read

                  关注个人公众号,有福利哦……

6、mysql事务的更多相关文章

  1. Mysql事务探索及其在Django中的实践(二)

    继上一篇<Mysql事务探索及其在Django中的实践(一)>交代完问题的背景和Mysql事务基础后,这一篇主要想介绍一下事务在Django中的使用以及实际应用给我们带来的效率提升. 首先 ...

  2. MySQL 事务

    MySQL 事务主要用于处理操作量大,复杂度高的数据.比如说,在人员管理系统中,你删除一个人员,你即需要删除人员的基本资料,也要删除和该人员相关的信息,如信箱,文章等等,这样,这些数据库操作语句就构成 ...

  3. mysql事务和并发控制

    谈到事务,首先想到的问题是并发控制.比如两个用户同时操作数据库里面的一张表,一个正在读数据,一个正在删除数据,那么读数据的读出的结果究竟是多少?并发可以提高系统的性能,让多个用户同时操作一份数据,但为 ...

  4. MySQL事务学习-->隔离级别

    MySQL事务学习-->隔离级别 6 事务的隔离级别 设置的目的 在数据库操作中,为了有效保证并发读取数据的正确性,提出的事务隔离级别. 数据库是要被广大客户所共享访问的,那么在数据库操作过程中 ...

  5. mysql 事务是专门用来管理insert,update,delete语句的,和select语句一点不相干

    1.mysql 事务是专门用来管理insert,update,delete语句的,和select语句一点不相干 2.一般来说,事务是必须满足4个条件(ACID): Atomicity(原子性).Con ...

  6. php mysql事务

    这里记录一下php操作mysql事务的一些知识 要知道,MySQL默认的行为是在每条SQL语句执行后执行一个COMMIT语句,从而有效的将每条语句独立为一个事务.但是,在使用事务时,是需要执行多条sq ...

  7. mysql事务问题

    mysql事务: 若mysql 开启事务后START TRANSACTION ,不显示提交commit,则默认自动回滚,而不是默认自动提交.

  8. MYSQL事务和锁

    mysql事务(一)—转载 2012年12月20日 ⁄ Mysql数据库, 技术交流 ⁄ 暂无评论 一. 什么是事务 事务就是一段sql 语句的批处理,但是这个批处理是一个atom(原子) ,不可分割 ...

  9. MySQL事务内幕与ACID

    MySQL的事务实现严格遵循ACID特性,即原子性(atomicity),一致性(consistency),隔离性(isolation),持久性(durability).为了避免一上来就陷入对ACID ...

  10. 数据库 Mysql事务详解

    Mysql事务 mysql的事务默认是自动提交的,也就是你提交一个query,他就直接执行!我们可以通过 禁止自动提交 开启自动提交 //mysql事务 #include <stdio.h> ...

随机推荐

  1. 19 JavaScript数组 &数组增删&最值&排序&迭代

    关联数组(散列) 关联数组又叫做散列,即使用命名索引. JavaScript数组只支持数字索引. JavaScript对象使用命名索引,而数组使用数字索引,JavaScript数组是特殊类型的对象. ...

  2. 吴裕雄 python 神经网络——TensorFlow ckpt文件保存方法

    import tensorflow as tf v1 = tf.Variable(tf.random_normal([1], stddev=1, seed=1)) v2 = tf.Variable(t ...

  3. Jmeter 如何发起一个post请求

    举例平台:https://www.juhe.cn/docs/api/id/65 前提条件: 1)要在聚合网站注册实名认证才可以收到Key,用于Get请求的参数数值 2)Jmeter本地安装好 3.这是 ...

  4. gym102220H 差分+树状数组(区间修改和输出)

    这题目很有意思,让我学会了树状数组的差分,更加深刻理解了树状数组 树状数组的差分写法 void add(int x,int k) { for (int i = x;i <= n;i += low ...

  5. 【PAT甲级】1066 Root of AVL Tree (25 分)(AVL树建树模板)

    题意: 输入一个正整数N(<=20),接着输入N个结点的值,依次插入一颗AVL树,输出最终根结点的值. AAAAAccepted code: #define HAVE_STRUCT_TIMESP ...

  6. print、println、printf的区别(转载)

    printf主要是继承了C语言的printf的一些特性,可以进行格式化输出   print就是一般的标准输出,但是不换行   println和print基本没什么差别,就是最后会换行   System ...

  7. linux 镜像备份工具rsnyc

    1.本地拷贝文件nohup rsync -avzh /data/wwwroot/xhprof/* /mnt/xhprof/ &2.更改文件夹名称mv /data/wwwroot/xhprof ...

  8. [IDEA] Idea复制文件到项目一直updating indices的问题

    通常我们在开发JavaWeb项目的时候,都需要先将网页写好,在进行复制到web目录下,如果里面包含了很多的资源文件,就会造成一直updating indices. 方法一: 这是因为项目需要对web目 ...

  9. springboot后端时间到前端,相差8小时,时间格式不对

    spring boot后台时间正确,返回给前台的时间不正确,和后台差8个小时 { "code": 1, "msg": "SUCCESS", ...

  10. Docker将自己的镜像发布到个人私有仓库

    Docker将自己的镜像发布到个人私有仓库 1.注册dockerhub账户 docker提供了一个类似于github的仓库dockerhub, 网址https://hub.docker.com/需要注 ...