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数据库事务
1. 什么是事务处理? 事务处理是一种机制,它是用来管理必须成批执行的mysql操作.来保证数据库不完整的操作结果. 2. 为什么要使用事务处理? 在使用mysql操作数据的过程中,如果只是简单的中小 ...
- MySQL的事务
MySQL的事务 1.事务:事务是由一步或者几步数据库操作序列组成的逻辑执行单元,这一系列操作要么全部执行,要么全部放弃执行. 2.事务具备的四个特性(简称为ACID性): (1)原子性(Atomic ...
- MySQL之事务隔离级别--转载
转自:http://793404905.blog.51cto.com/6179428/1615550 本文通过实例展示MySQL事务的四种隔离级别. 1 概念阐述 1)Read Uncommitted ...
- mysql数据库事务详细剖析
在写之前交代一下背景吧! 做开发也好久了,没怎么整理过知识,现在剖析一下自己对数据库事务的认识,以前用sqlserver,现在转java后又用mysql.oracle.我这块就主要解释一下mysql数 ...
- Mysql数据库事务隔离级别
事务(transaction)是数据库管理系统的执行单位,可以是一个数据库操作(如Select操作)或者是一组操作序列.事务ACID属性,即原子性(Atomicity).一致性(Consistency ...
- 《高性能Mysql》解读---Mysql的事务和多版本并发
1.base:ACID属性,并发控制 2.MySql事务的隔离级别有哪些,含义是什么? 3.锁知多少,读锁,写锁,排他锁,共享锁,间隙锁,乐观锁,悲观锁. 4.Mysql的事务与锁有什么关联?MySq ...
- Mysql加锁过程详解(2)-关于mysql 幻读理解
Mysql加锁过程详解(1)-基本知识 Mysql加锁过程详解(2)-关于mysql 幻读理解 Mysql加锁过程详解(3)-关于mysql 幻读理解 Mysql加锁过程详解(4)-select fo ...
- Mysql加锁过程详解(3)-关于mysql 幻读理解
Mysql加锁过程详解(1)-基本知识 Mysql加锁过程详解(2)-关于mysql 幻读理解 Mysql加锁过程详解(3)-关于mysql 幻读理解 Mysql加锁过程详解(4)-select fo ...
- MySQL数据库事务各隔离级别加锁情况--Repeatable Read && MVCC(转)
本文转自https://m.imooc.com/article/details?article_id=17289 感谢作者 上节回顾 上两篇记录了我对MySQL 事务 隔离级别read uncommi ...
随机推荐
- 如何创建LocalDB数据库和数据库实例
LocalDB是SQL Server 2012带来的新特性,它是一个专门为开发人员量身定制的轻量级数据库,下面介绍如何使用它. 创建LocalDB数据库的方法: 打开服务器资源管理器,右键点击“数据连 ...
- [剑指Offer] 8.跳台阶
题目描述 一只青蛙一次可以跳上1级台阶,也可以跳上2级.求该青蛙跳上一个n级的台阶总共有多少种跳法. [思路]与斐波那契数列类似 class Solution { public: int jumpF ...
- Failed with exception MetaException(message:javax.jdo.JDODataStoreException: Error(s) were found while auto-creating/validating the datastore for classes.
hive (db_emp)> load data local inpath '/opt/datas/emp.txt' into table emp_part partition(`date`=' ...
- BZOJ1787 [Ahoi2008]Meet 紧急集合 【LCA】
1787: [Ahoi2008]Meet 紧急集合 Time Limit: 20 Sec Memory Limit: 162 MB Submit: 3578 Solved: 1635 [Submi ...
- 【NOIP模拟赛】就 反悔贪心
biubiu~~~ 这道题,考场上上来就dp然后发现怎么优化也不行.............最后发现是贪心............. 正解:带反悔的贪心,原理是,假设我们现在得到了取i个的最优解那么我 ...
- 使用UMeditor富文本编辑器上传图片
注:本文系作者原创,但可随意转载. 最近写自己的网站玩儿,写到博客的部分,打算使用UMeditor,因为之前也用过(但是好像没实现图片上传的功能),感觉用起来还比较简单. 不过还是折腾了一下午...遇 ...
- 问题总结——window平台下grunt\bower安装后无法运行的问题
一.问题: 安装grunt或者bower后,在cmd控制台运行grunt -version 或者 bower -v会出现:“xxx不是内部或外部命令,也不是可运行的程序或批处理文件”,
- hibernate连接oracle数据库
前言:以下所有的操作都是基于你已经成功安装了oracle数据库并且java的开发环境正常的情况下进行的. 如果没有完善请先配置基础环境. 第一步:配置需要的环境(下载并导入需要的包). 下载链接:ht ...
- 2、Distributed Optimization
一.目录: Distributed dynamic programming (as applied to path-planning problems). Distributed solutions ...
- MVC前台获取ViewData的数组中的值
查了一上午资料,找到了一种比较有效的方法 后台控制器:public ActionResult Index() { List<string> colors = new List<str ...