mysql 转账语句_MySQL事务-学习笔记

MySQL事务

事务的意义

案例:银行转账过程

A向B转账500,A原来有1000,B有500。

分析:

SQL处理过程:

A 减少 500

B 增加 500

以上两点必须同时生效,才算合理。

核心:要么都成功,要么都失败

事务(Transaction):一个最小的不可再分的工作单元;通常一个事务对应一个完整的业务(例如银行账户转账业务,该业务就是一个最小的工作单元)

事务管理(ACID)

原子性(Atomicity)

原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。

以上述例子为例:

转账成功:A 转出500,B转入500是同时发生的。

转账失败:A 转出500失败,B不会转入500。

转账要么都成功,要么都失败,不能只发生一个动作,比如A少了500,但B没加。

一致性(Consistency)

事务前后数据的完整性必须保持一致。

无论怎么转总价值 1500,不会少。

持久性(Durability)

持久性是指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来即使数据库发生故障也不应该对其有任何影响

事务没有提交,则恢复到原状

事务如果提交,则不可逆

隔离性(Isolation)

事务的隔离性是多个用户并发访问数据库时,数据库为每一个用户开启的事务,不能被其他事务的操作数据所干扰,多个并发事务之间要相互隔离。

A给B转账,C给B转账。两个是独立的,不会相互影响。

常见问题

脏读

指一个事务读取了另一个事务未提交的数据。

举例:

A :1000 B:500 C:1000

首先A 转账给B 500,记为事务1,此时A:500 B:1000,但事务没结束,结果还未提交。

这时C 也转账给B 500,该事务中B的初始值是500,C是1000,转账后 B:1000 ,C:500。

事务1提交结果,A:500,B:1000。

事务2提交结果,B:1000,C:500。

最后结果:A:500 B:1000 C:500,B 少了500!

错误原因是事务2读取的B的余额不准确。

不可重复读

在一个事务内读取表中的某一行数据,多次读取结果不同。(这个不一定是错误,只是某些场合不对)

比如报表功能,包含查询、生成报表,查询的时候,A :1000 B:500。在生成报表前,提交A完成转账500给B的事务,最终生成的报表中,A:500,B:1000

虚读(幻读)

和上面类似,是指在一个事务内读取到了别的事务插入的数据,导致前后读取不一致。

(一般是行影响,多了一行。)

执行事务

MySQL是默认开启事务自动提交的,需要关闭。语句如下:

SET autocommit = 0 -- 关闭

SET autocommit = 1 -- 开启(默认的)

手动处理事务:

关闭事务自动提交 SET autocommit = 0

开启事务(标记一个事务的开始,之后的语句都在同一个事务内) Start transaction

写SQL语句……

执行操作

提交(成功,持久化到数据库) commit

回滚(失败,回到原来的样子) rollback

事务结束

打开事务自动提交

其他(了解即可)

事务语句较多时,可以设置保存点 savepoint

回滚到保存点 rollback to savepoint

释放保存点 release savepoint

案例:实现一个转账事务,A向B转账500

-- 创建数据库 Bank

CREATE DATABASE `Bank` CHARACTER SET utf8 COLLATE utf8_general_ci;

-- 创建表

CREATE TABLE `account`(

`id` INT(4) AUTO_INCREMENT NOT NULL,

`name` VARCHAR(20) NOT NULL,

`money` DECIMAL(9,2) NOT NULL,

PRIMARY KEY(`id`)

)ENGINE INNODB DEFAULT CHARSET=utf8;

-- 插入A和B的账户数据

INSERT INTO `account`(`name`,`money`) VALUES ('A','1000.00'),('B','500.00');

-- 转账事务处理

-- 关闭事务自动提交

SET autocommit=0;

-- 开启事务

START TRANSACTION;

-- 写SQL语句

-- A - 500

UPDATE `account` SET money=money-500 WHERE `name`='A';

-- B + 500

UPDATE `account` SET money= money+500 WHERE `name`='B';

-- 提交事务

COMMIT;

-- 重新打开事务自动提交

SET autocommit=1;

以上为事务相关的基础内容学习记录及案例练习。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值