-- 设置数据库事务为手动的提交
SET @@AUTOCOMMIT = 0;

-- 查看是否被修改
SELECT @@autocommit;

-- 查看当前的编码格式
SELECT @@character_set_results;

-- 账户表
CREATE TABLE account(
id INT PRIMARY KEY AUTO_INCREMENT,
NAME VARCHAR(20),
balance INT
);

INSERT INTO account(NAME,balance) VALUES('mzy',5000);
INSERT INTO account(NAME,balance) VALUES('jacky',5000);

SELECT * FROM account;
UPDATE account SET balance=5000;
DELETE FROM account;

-- 设置为手动提交之后,必须手动commit
COMMIT;

-- 关于事务的四种特性中的隔离性的理解:
-- 1.首先调整数据库事务隔离性的级别
-- 隔离级别 脏读 不可重复读 幻读
-- Serializable         否          否           否
-- Repeatable Read      否          否           是
-- Read Committed       否          是           是
-- Read Uncommitted     是          是           是

-- mysql默认的话: Repeatable Read
-- oracle默认的话:Read Committed

-- 修改事务的等级:最低的级别Read Uncommitted:
SET GLOBAL TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
-- 1. 测试脏读
-- 查看当前的级别:
SELECT @@global.tx_isolation;

脏读的理解:
一个事务读到了另一个事务未提交更新的数据!
假如这个事务未commit,只是当前操作可以看见,
但是未提交事务!

例如具体业务中:
买家点击货物(假定价格100元),进入付款的界面了,
但是没有执行最后的提交付款(COMMIT),但是也没有
取消订单(ROLLBACK)【注意是相当于保持这个操作】。
但是通知卖家查看余额的时候,就会发现余额多了100元,
卖家一发货,就相当于损失了100元。

SET @@AUTOCOMMIT = 0; -- 首先设置事务提交为手动

-- 我先给卖家jacky打2000,让他发货
UPDATE account SET balance=balance-2000 WHERE NAME='mzy';
UPDATE account SET balance=balance+2000 WHERE NAME='jacky';

-- jacky查余额增加了2000
SELECT * FROM account WHERE NAME='jacky';

-- 然后我取消订单进行混滚了
ROLLBACK;

-- 修改事务的等级:倒数第二级别Read Committed:
-- read committed 比 read uncommitted 多了防止脏读
SET GLOBAL TRANSACTION ISOLATION LEVEL READ COMMITTED;
-- 2. 测试不可重复读
-- 查看当前的级别:
SELECT @@global.tx_isolation;

不可重复读:
一个事务得到了另一个事务已提交更新(update)的数据!

需要和上面的脏读区分出来的是,我们的脏读是站在用户的角度来看的;
但是不可重复读,是站在银行的角度来讲的,在银行的需求中,当前的
报备和日志需要统一!!
什么意思呢?
比如在一次银行对用户的存款进行查账的操作中,操作的数据
保持一致!
例如:我们当前的正在查A用户,查到A用户的存款有3000元,
但是在我们开始记录的那一个时刻点,A用户又进行存款的操作;
A用户又存了2000元;如果没有预防不可重复读的话,那么在一次
事务的操作中,如果需要多次记录结果:第一次记录结果就为3000元;
第二次记录结果就为5000元,造成两个记录的结果不同;

意思就是,两个并发进行的事务不能相互影响,这种修改的结果,只能在
当前事务结束了之后,存入,修改!

脏读是必须避免的,但是不可重复读,有些时候也是需要的;

-- 不可重复读的测试应该是两个窗口才能进行:不可重复读原理是并发并行的事务;

-- 模拟:窗口一
-- jacky存入2000元
UPDATE account SET balance = banlance + 2000 WHERE account.`NAME` = 'jacky';

-- 模拟:窗口二(在窗口一的update操作前打开)
-- 在没有防止不可重复读的时候,这里的结果应该是修改了之后的结果
-- 在防止了不可重复读之后,这里的结果应该是修改前的,
-- 当退出当前事务之后,再次进入事务,才是修改后的结果。
SELECT account.`balance` FROM account WHERE account.`NAME` = 'jacky';







-- 修改事务的等级:倒数第三级别REPEATABLE READ:
SET GLOBAL TRANSACTION ISOLATION LEVEL REPEATABLE READ;
-- 3.测试幻读
-- 查看当前的级别:
SELECT @@global.tx_isolation;

幻读:
一个事务读到另一个事务,新插入(insert)的数据。
mysql中看不到幻读,但是能防止幻读?
只能看最高级别防止了幻读后倒推!

SET GLOBAL TRANSACTION ISOLATION LEVEL SERIALIZABLE;

-- 假如,现在银行中新加了一个用户,也是并发的事务;
-- 其中如果是显示添加前的mzy和jacky两个账户就是防止了幻读
-- 如果计算上了新加的用户,就是幻读

-- 窗口一:
SELECT COUNT(account.`NAME`) FROM account;

-- 窗口二:
-- mysql中看不到幻读
INSERT INTO account VALUES(....); -- 直接卡住,不会让你插入
-- 因为如果你插入的话,就会影响到上面的查询

-- 倒推:如果没有防止幻读的话,级别不是SERIALIZABLE,而是REPEATABLE READ
-- 就会在一次查询中并发的两个事务,产生幻读首先查询count(*)为2
-- 在insert之后,查询就为3

-- 和防止可重复读不同的是,可重复读运行用户修改(update),但是另一个事务当前不会
-- 发生变化,在重新开启的时候才会发生变化。

-- 防止幻读就很简单粗暴,当在查询的时候,就禁止用户开户(insert)

-- 隔离等级:但是安全性往往会带来性能上的缺失
-- 我觉得在一般的业务中防止脏读就可以了,可重复读和幻读都是可以接受的。

我对数据库事务的理解(MYSQL中)的更多相关文章

  1. 数据库事务系列-MySQL跨行事务模型

    说来和MySQL倒是有缘,毕业的第一份工作就被分配到了RDS团队,主要负责把MySQL弄到云上做成数据库服务.虽说整天和MySQL打交道,但说实话那段时间并没有很深入的理解MySQL内核,做的事情基本 ...

  2. 如何理解 MySQL 中的 <=> 操作符?

    问题 : 我在看以前的一个开发者的代码时看到 WHERE p.name <=> NULL 在这个查询语句中 <=>符号是什么意思啊?是不是和 =号是一样啊?还是一个语法错误啊? ...

  3. 正确理解MySQL中的where和having的区别

    原文:https://blog.csdn.net/yexudengzhidao/article/details/54924471 以前在学校里学习过SQLserver数据库,发现学习的都是皮毛,今天以 ...

  4. Sybase数据库实现等效的mysql中group_concat功能

    在MySQL中,如果想实现将分组之后的多个数据合并到一列,可以使用group_concat函数,如下图所示: 但是,在Sybase中没有这样的函数(别问我为什么使用Sybase,因为公司用的Sybas ...

  5. 如何理解MySQL中auto_increment?

    1.auto_increment用于主键自动增长.比如从1开始增长,当把第一条数据删除,再插入第二条数据时,主键值为2,不是1.

  6. 深入理解MySQL中的Redo、Undo、MVCC

    http://edu.csdn.net/course/detail/3495 http://edu.csdn.net/courses/o317_a3/云计算大数据

  7. 数据库事务中的隔离级别和锁+spring Transactional注解

    数据库事务中的隔离级别和锁 数据库事务在后端开发中占非常重要的地位,如何确保数据读取的正确性.安全性也是我们需要研究的问题.ACID首先总结一下数据库事务正确执行的四个要素(ACID): 原子性(At ...

  8. 深入理解 MySQL ——锁、事务与并发控制

    本文首发于vivo互联网技术微信公众号 mp.weixin.qq.com/s/JFSDqI5ya… 作者:张硕 本文对 MySQL 数据库中有关锁.事务及并发控制的知识及其原理做了系统化的介绍和总结, ...

  9. 举例说明MySQL中的事务

    一.场景导入 现在有一张仓库表,仓库表中记录了每一个物品的数量,还有一张用户表,用户购买产品,仓库表的产品数量减少,而用户拥有产品的数量增加. 但是如果仓库中的产品数量不足时怎么处理? 例子: #仓库 ...

随机推荐

  1. File类与常用IO流第八章——缓冲流

    第八章.缓冲流 缓冲流概述 缓冲流,也叫高效流,是对4个基本的FileXxx流的增强.按照数据类型分为4类:   输入缓冲流 输出缓冲流 字节缓冲流 BufferedInputStream Buffe ...

  2. Spring总结之SpringMvc下

    五.拦截器 SpringMVC中的拦截器是通过HandlerInterceptor来实现的,定义一个Interceptor有两种方式 1.实现HandlerInterceptor接口或者继承实现了Ha ...

  3. awk对某个字段分割处理

    工作中遇到要根据文件中某个字段分割成多行文本的处理,想到用awk处理,这里记录下: 问题: 原文件:假设一共2个字段,用"|"分割,其中第二个字段用"#"分割, ...

  4. IO编程之对象序列化

    对象序列化的目标是将对象保存在磁盘中或者允许在网络中直接传输对象.对象序列化机制循序把内存中的java对象转换成平台无关的二进制流,从而允许把这种二进制流持久的保存在磁盘上,通过网络将这种二进制流传输 ...

  5. CentOS 7安装Python3 笔记

    当前系统为阿里云的CentOS7.3 64位操作系统. 为了能让后续安装的软件(django,uwsgi,nginx等)尽量减少出现bug的几率,先把可能的依赖包都安装上. 一.安装依赖包 yum - ...

  6. 网络损伤仪WANsim的功能与型号

    网络损伤仪简介 WANsim网络损伤仪是一款可以模拟真实的广域网状况的设备.它可以通过简单的数据填写模拟出时延.带宽抖动.丢包.乱序.误码.报文重复等网络状况. 大多数公司在进行产品测试时,只关注了应 ...

  7. 【洛谷P2623物品选取】动态规划

    分析 各种背包弄在一起. AC代码 // luogu-judger-enable-o2 #include <bits/stdc++.h> using namespace std; #def ...

  8. 第二十九篇 -- UDP和TCP

    最近在写WIFI模块,所以就想明确一些TCP和UDP的区别,发现以前的理解还是有点误区.现在重新学习. 相同点 UDP协议和TCP协议都是传输层协议 TCP(Transmission Control ...

  9. Vmware 虚拟机网络通讯

    VMware Workstation(中文名"威睿工作站")是一款功能强大的桌面虚拟计算机软件,提供用户可在单一的桌面上同时运行不同的操作系统,和进行开发.测试 .部署新的应用程序 ...

  10. VS2013导入新项目时,连接数据库问题。

    用VS2013导入项目进行学习时,导入数据库会报数据库登陆不上的错误... 解决方法: 1.将其自带的数据库连接先删除,使用自己的sql server数据库将项目数据库先附加进去, 2.附加进去后,再 ...