MySQL---事务知识,你搞明白没有?
MySQL - 事务
在学习事务这一概念前,我们需要需要构思一个场景
场景构思
假设该场景发生于一个银行转账背景下,月中,又到了发工资的日子。学校打算给A老师发放一个月的工资。(此处,我们假设转账都是由人工操作的),整个过程本应该如下:
学校财务核对A老师工资单
确认学校账上还有这么多钱
向银行提出转账申请,银行扣除学校财务卡上的指定金额
银行向A老师工资卡打入指定金额
银行汇报双方交易完成
但是,当这个过程执行完第3步的时候,突然大断电!整个电力系统进入瘫痪。待电力系统回复之后,银行并不会继续执行4、5步甚至连1,2,3步的操作记录都丢失了。此时出现了如下的问题:
学校认为,工资已经发出
A老师认为,学校还没有发工资
银行认为,从来就没有发生过转账的事情
其实整个过程可以用一个词来描述:数据库中的数据产生了“不一致性”
一致性
上述背景中设计到了一个概念,叫做不一致性,这是和一致性相对的概念。那么,什么是一致性呢?
一致性的意思是,在一系列数据库行为的前后两个时间点上,数据是正确对应的。放在上面的例子来看,就是操作前后,两个账户的总金额是一样的,这样就保证不会凭空的丢失掉不该丢失掉的金钱。
原子操作
为了保证数据的一致性,我们可以将一系列会破坏一致性的操作声明为原子操作。被声明为原子操作的那些操作要么一起完成,要么一起失败,这样我们就避免了类似断电这类情况导致的数据不一致性。
事务
那么如何才能实现MySQL中的原子操作呢?
MySQL以及大多数关系型数据库都提供了一个叫做事务的技术。我们可以声明一个事务的开始,在确认提交或者指明放弃前的所有操作,都先在一个叫做事务日志的临时环境中进行操作。待操作完成,确保了数据一致性之后,那么我们可以手动确认提交,也可以选择放弃以上操作。
注意: 一旦选择了提交,那么便不能再利用放弃操作来撤销更改了。
案例分析
我们首先创建我们本次案例需要使用的表,并给一些测试数据
mysql> SHOW DATABASES;#查看有多少数据库
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| python |
| sys |
+--------------------+
5 rows in set (0.00 sec)
mysql> USE `python`;#切换数据库
Database changed
mysql> SELECT DATABASE();#查看当前使用的数据库
+------------+
| DATABASE() |
+------------+
| python |
+------------+
1 row in set (0.00 sec)
mysql> CREATE TABLE `account` (
-> `id` int PRIMARY KEY AUTO_INCREMENT,
-> `name` VARCHAR(20) NOT NULL,
-> `balance` DECIMAL(12,2)
-> );
Query OK, 0 rows affected (0.04 sec)
mysql> INSERT INTO `account`(`name`, `balance`)
-> VALUES ('TanzhouEDU', 10000000),('Tuple', 10000)
-> ;
Query OK, 2 rows affected (0.70 sec)
Records: 2 Duplicates: 0 Warnings: 0
断电案例(非原子操作)
首先,查看现有的账户情况
mysql> SELECT * FROM `account`;
+----+------------+-------------+
| id | user | balance |
+----+------------+-------------+
| 1 | TanzhouEDU | 10000000.00 |
| 2 | Tuple | 10000.00 |
+----+------------+-------------+
2 rows in set (0.00 sec)
现在,学校财务开始向A老师发工资
mysql> UPDATE `account`
-> SET `balance` = `balance` - 10000
-> WHERE `user` = 'TanzhouEDU'
-> ;
Query OK, 1 row affected (0.05 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> SELECT * FROM `account`;
+----+------------+------------+
| id | user | balance |
+----+------------+------------+
| 1 | TanzhouEDU | 9990000.00 |
| 2 | Tuple | 10000.00 |
+----+------------+------------+
2 rows in set (0.00 sec)
此时,发生了断电,再登录数据库以后,钱已经消失了。
事务案例(原子操作)
MySQL中,事务操作包括4个:
START TRANSACTION:开始一个新的事务COMMIT:提交当前事务,做出永久改变ROLLBACK:回滚当前事务,放弃修改SET autocommit = {0 | 1}:对当前会话禁用(0)或启用(1)自动提交模式我们利用事务机制来重复上述断电的情况。看看是否能够有所帮助。
mysql> SELECT * FROM `account`;
+----+------------+------------+
| id | user | balance |
+----+------------+------------+
| 1 | TanzhouEDU | 9990000.00 |
| 2 | Tuple | 10000.00 |
+----+------------+------------+
2 rows in set (0.00 sec)
mysql> START TRANSACTION;
Query OK, 0 rows affected (0.00 sec)
mysql> UPDATE `account`
-> SET `balance` = `balance`-1000
-> WHERE `user` = 'TanzhouEDU'
-> ;
Query OK, 1 row affected (0.01 sec)
mysql> SELECT * FROM `account`;
+----+------------+------------+
| id | user | balance |
+----+------------+------------+
| 1 | TanzhouEDU | 9989000.00 |
| 2 | Tuple | 10000.00 |
+----+------------+------------+
2 rows in set (0.00 sec)
mysql> exit
Bye
tuple@MyVM:~$ mysql -utuple -p123456
mysql> USE `python`;
Database changed
mysql> SELECT * FROM `account`;
+----+------------+------------+
| id | user | balance |
+----+------------+------------+
| 1 | TanzhouEDU | 9990000.00 |
| 2 | Tuple | 10000.00 |
+----+------------+------------+
2 rows in set (0.00 sec)
我们可以看到,数据在断电后,自动恢复到了数据修改前的样子,它相当于如下一个操作过程。
mysql> START TRANSACTION;
Query OK, 0 rows affected (0.00 sec)
mysql> UPDATE `account`
-> SET `balance`=`balance`-1000
-> WHERE `user`='TanzhouEDU'
-> ;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> SELECT * FROM `account`;
+----+------------+------------+
| id | user | balance |
+----+------------+------------+
| 1 | TanzhouEDU | 9989000.00 |
| 2 | Tuple | 10000.00 |
+----+------------+------------+
2 rows in set (0.00 sec)
mysql> ROLLBACK;
Query OK, 0 rows affected (0.02 sec)
mysql> SELECT * FROM `account`;
+----+------------+------------+
| id | user | balance |
+----+------------+------------+
| 1 | TanzhouEDU | 9990000.00 |
| 2 | Tuple | 10000.00 |
+----+------------+------------+
2 rows in set (0.00 sec)
接着,我们来做一次正确的操作,真正的给A老师发一次工资。
mysql> START TRANSACTION;
Query OK, 0 rows affected (0.00 sec)
mysql> UPDATE `account`
-> SET `balance` = `balance`-10000
-> WHERE `user` = 'TanzhouEDU'
-> ;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> UPDATE `account`
-> SET `balance` = `balance`+10000
-> WHERE `user`= 'Tuple'
-> ;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> SELECT * FROM `account`;
+----+------------+------------+
| id | user | balance |
+----+------------+------------+
| 1 | TanzhouEDU | 9980000.00 |
| 2 | Tuple | 20000.00 |
+----+------------+------------+
2 rows in set (0.00 sec)
mysql> COMMIT;
Query OK, 0 rows affected (0.03 sec)
mysql> ROLLBACK;
Query OK, 0 rows affected (0.00 sec)
mysql> SELECT * FROM `account`;
+----+------------+------------+
| id | user | balance |
+----+------------+------------+
| 1 | TanzhouEDU | 9980000.00 |
| 2 | Tuple | 20000.00 |
+----+------------+------------+
2 rows in set (0.00 sec)
通过上面的例子可以看出,一旦commit了,那么rollback还是断电都不能反悔了。
MySQL---事务知识,你搞明白没有?的更多相关文章
- 【转】MYSQL DBA知识了解-面试准备
http://www.itpub.net/forum.php?mod=viewthread&tid=1825849 公司招聘MySQL DBA,也面试了10个2年MySQL DBA工作经验的朋 ...
- MYSQL事务之Yii2.0商户提现
我是一个半路出家的PHP程序员,到目前为止,不算在培训班学习的时间,已经写代码整整两年了.可能由于工作业务的原因,在这两年中我没有用到过MySQL事务.就在昨天有个关于支付宝转账的业务不得不使用MyS ...
- mysql事务隔离级别、脏读、幻读
Mysql事务隔离级别本身很重要,再加上可能是因为各大公司面试必问的缘故,在博客中出现的概率非常高,但不幸的是,中国的技术博客要么是转载,要么是照抄,质量参差不齐,好多结论都是错的,对于心怀好奇之心想 ...
- Mysql 事务及其原理
Mysql 事务及其原理 什么是事务 什么是事务?事务是作为单个逻辑工作单元执行的一系列操作,通俗易懂的说就是一组原子性的 SQL 查询.Mysql 中事务的支持在存储引擎层,MyISAM 存储引擎不 ...
- MySQL 基础知识梳理
MySQL 的安装方式有多种,但是对于不同场景,会有最适合该场景的 MySQL 安装方式,下面就介绍一下 MySQL 常见的安装方法,包括 rpm 安装,yum 安装,通用二进制安装以及源码编译安装, ...
- 一文彻底读懂MySQL事务的四大隔离级别
前言 之前分析一个死锁问题,发现自己对数据库隔离级别理解还不够清楚,所以趁着这几天假期,整理一下MySQL事务的四大隔离级别相关知识,希望对大家有帮助~ 事务 什么是事务? 事务,由一个有限的数据库操 ...
- MySQL 事务常见面试题总结 | JavaGuide 审核中
<Java 面试指北>来啦!这是一份教你如何更高效地准备面试的小册,涵盖常见八股文(系统设计.常见框架.分布式.高并发 ......).优质面经等内容. 本文原发于 MySQL知识点&am ...
- mysql事务和并发控制
谈到事务,首先想到的问题是并发控制.比如两个用户同时操作数据库里面的一张表,一个正在读数据,一个正在删除数据,那么读数据的读出的结果究竟是多少?并发可以提高系统的性能,让多个用户同时操作一份数据,但为 ...
- Mysql数据库知识-Mysql索引总结 mysql mysql数据库 mysql函数
mysql数据库知识-Mysql索引总结: 索引(Index)是帮助MySQL高效获取数据的数据结构. 下边是自己整理的资料与自己的学习总结,,做一个汇总. 一.真的有必要使用索引吗? 不是每一个性能 ...
随机推荐
- Google Guice学习
学习动力:公司项目使用 官方文档:https://github.com/google/guice/wiki/Motivation 学习阶段:入门 主要部份: 简介 Bindings方式 Scopes设 ...
- 转:微信开发获取地理位置实例(java,非常详细,附工程源码)
微信开发获取地理位置实例(java,非常详细,附工程源码) 在本篇博客之前,博主已经写了4篇关于微信相关文章,其中三篇是本文基础: 1.微信开发之入门教程,该文章详细讲解了企业号体验号免费申请与一 ...
- [Netty] - Netty入门(最简单的Netty客户端/服务器程序)
Java中的NIO是一种解决阻塞式IO问题的基本技术,但是NIO的编写对java程序员是有比较高的要求的.那么Netty就是一种简化操作的一个成熟的网络IO编程框架.这里简单介绍一个程序,代码是< ...
- android学习12——重载SurfaceView一些方法的执行顺序
先看代码 public class SurfaceViewActivity extends Activity { @Override public void onCreate(Bundle saved ...
- Unity3d中如何混用三种脚本语言?
首先要明白,这三种说的混用是指文件级别的混用,就是说一个文件是由一种语言写的.而不是说你这一个文件可以混用这三种语言,注意这是不允许的. 第二要明白,在unity3d中为什么可以使用三种语言混合开发? ...
- Dijkstra算法的二叉堆优化
Dijkstra算法的二叉堆优化 算法原理 每次扩展一个距离最小的点,再更新与其相邻的点的距离. 如何寻找距离最小的点 普通的Dijkstra算法的思路是直接For i: 1 to n 优化方案是建一 ...
- Ceph部署(二)RGW搭建
背景 Ceph RGW简介 Ceph RGW基于librados,是为应用提供RESTful类型的对象存储接口.RGW提供两种类型的接口: 1) S3:兼容Amazon S3RESTful API: ...
- SVN的具体使用方法介绍(安装以及操作)
今天由于项目的需要安装了SVN,在这里和大家分享一下SVN安装的详细过程和分享一些资料. (1)首先是客户端的安装. 1)获取客户端安装包. --安装包的获取路径: TortoiseSVN的官方下载地 ...
- MJRefresh在UITableView中的使用
前言 MJRefresh是一个好用的上下拉刷新的控件,github地址如下:https://github.com/CoderMJLee/MJRefresh 很多app都使用这个控件,我们也来了解一下它 ...
- Kubernetes运维生态-cAdvisor分析
Kubernetes的生态中,cAdvisor是作为容器监控数据采集的Agent,其部署在每个节点上,内部代码结构大致如下:代码结构很良好,collector和storage部分基本可做到增量扩展开发 ...