史上最简单的 MySQL 教程(三十八)「事务(上)」

温馨提示:本系列博文已经同步到 GitHub,地址为「mysql-tutorial」,欢迎感兴趣的童鞋StarFork,纠错。

案例:银行的数据库里面存储着用户的账户信息表,当用户 A 想用户 B 转账的时候,正常情况下,A 账户的余额减少,B 账户的余额增加;但是由于某种原因(例如突然断电),当 A 账户的余额减少之后,B 账户的余额并没有增加,这就造成了数据库数据的安全隐患。

解决方案:当 A 账户的余额减少之后,不要立即修改数据表,而是在确认 B 账户的余额增加之后,同时修改数据表。

事务

通过前面的案例及解决方案,我们就引出了一个全新的概念,那就是:事务,即

  • 一系列将要发生或正在发生的连续操作。

事务安全,是一种保护连续操作同时实现(完成)的机制。事务安全的意义就是,保证数据操作的完整性

首先,执行如下 SQL 语句,创建银行账户表并插入数据:

-- 创建银行账户表
create table bank_account(
	id int primary key auto_increment,
	cardno varchar(16) not null unique comment 'bank card number',
	name varchar(20) not null,
	money decimal(10,2) default 0.0 comment 'account balance' 
)charset utf8;

-- 插入数据
insert into bank_account values
(null, '0000000000000001', 'Charies', 8000),
(null, '0000000000000002', 'Gavin', 6000);
1

接下来,让我们一起了解事务的操作。

事务操作

事务操作,分为两种:自动事务(默认的),手动事务

在这里,以银行账户的余额增减为例,我们来了解手动事务的操作流程。

第 1 步:开启事务,告诉系统以下所有操作,不要直接写入数据库,先存到事务日志。

  • 基本语法start transaction;

执行如上 SQL 语句,开启事务:

-- 开启事务
start transaction;
2

第 2 步:减少 Charies 账户的余额

-- 更新 Charies 账户余额
update bank_account set money = money - 1000 where id = 1;
-- 查询 bank_account 表数据
select * from bank_account;
3

如上图所示,Charies 账户的余额显示减少1000,但实际上,由于我们开启了事务,数据表真实的数据,并没有同步更新。为了验证这个论断,我们重新打开一个数据库客户端,查询bank_account表的数据:

4

如上图所示,显然数据库的事务安全机制起了作用,当我们开启(手动)事务之后,其后一系列操作并没有直接写入数据库,而是存入了事务日志。在这里,我们并没有打开数据库事务的日志进行验证,因为事务日志存储的是经过编译之后的字节码文件。

第 3 步:增加 Gavin 账户的余额

-- 更新 Gavin 账户余额
update bank_account set money = money + 1000 where id = 2;
-- 查询 bank_account 表数据
select * from bank_account;
5

如上图所示,Gavin 账户的余额显示增加1000,但是,由于我们开启了事务,数据表真实的数据,仍然没有同步更新。

第 4 步:提交事务或回滚事务

  • 提交事务基本语法commit;
  • 回滚事务基本语法rollback;

如果我们选择提交事务,则将事务日志存储的记录直接更新到数据库,并清除事务日志;如果我们选择回滚事务,则直接将事务日志清除,所有在开启事务至回滚事务之间的操作失效,保持原有的数据库记录不变。在这里,我们以提交事务为例:

-- 提交事务
commit;
-- 查询 bank_account 表数据
select * from bank_account;
6

如上图所示,当我们提交事务之后,数据库的真实记录更新,两个客户端的数据一致。

在此,值得我们注意的是:当我们提交事务之后,在进行回滚事务是不起作用的,因为事务日志在提交事务的同时已经被清除啦

此外,我们还要知道:现阶段,只有 InnoDB 和 BDB 两个存储引擎是支持事务安全机制的,其中 InnoDB 免费,BDB 收费。因此,InnoDB 使用的最为广泛。


温馨提示:符号[]括起来的内容,表示可选项;符号+,则表示连接的意思。


———— ☆☆☆ —— 返回 -> 史上最简单的 MySQL 教程 <- 目录 —— ☆☆☆ ————

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

编辑于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏pangguoming

CentOS7 安装 mysql8

本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/ManagementAndJava/article/details/80...

2482
来自专栏Eternally运维

个人认为比较重要的MySQL—innodb参数详解

innodb_io_capacity:脏页的刷新的数量,可以动态调整,默认是200,该参数的设置取决于硬盘的IOPS的大小,IOPS就是每秒的读写次数。

1556
来自专栏JAVA同学会

MongoDB之分片集群(Sharding)

  分片(sharding)是一个通过多台机器分配数据的方法。MongoDB使用分片支持大数据集和高吞吐量的操作。大数据集和高吞吐量的数据库系统挑战着单一服务的...

1362
来自专栏我是攻城师

ElasticSearch的一些删除用法笔记

3447
来自专栏aoho求索

基于可靠消息方案的分布式事务(三):Lottor使用

前面两篇文章介绍了笔者关于可靠消息方案的分布式事务的实现思路以及Java中的事务概念,奈何工作抽不出时间,如今时隔已久,分布式事务系列拖了很久,一直没能好好把项...

631
来自专栏Laoqi's Linux运维专列

MySQL调优

4109
来自专栏LanceToBigData

MySQL集群(一)之主从复制

前面学完了JDBC,接下来带大家感受一下MySQL集群!其实什么是MySQL集群?简单的说就是一群机器(服务器)的集合,它们连在一起来工作。 其实各种数据库都有...

2045
来自专栏小白客

学习SQL【1】-搭建SQL的学习环境

最近我在学习SQL,现在就开始记录我的学习过程吧,加油!如果你也想学SQL,希望我的学习记录能对你有所帮助。 PostgreSQL是对象关系型数据库管理系统...

3276
来自专栏你不就像风一样

CentOS 6.5下RPM方式(重新)安装MySQL 5.7.21从头到尾篇

ERROR 1290 (HY000): The MySQL server is running with the --skip-grant-tables ...

702
来自专栏LIN_ZONE

远程连接ubuntu mysql出现2003错误 cant connect to mysql(转载)

2.打开my.cnf文件,找到 bind-address = 127.0.0.1 在前面加上#注释掉,如下: #bind-address = 127.0.0....

862

扫码关注云+社区