ICode9

精准搜索请尝试: 精确搜索
首页 > 数据库> 文章详细

MySQL事务-学习笔记

2021-02-07 18:02:47  阅读:154  来源: 互联网

标签:转账 事务 -- 笔记 提交 MySQL 500 1000


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;

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

标签:转账,事务,--,笔记,提交,MySQL,500,1000
来源: https://www.cnblogs.com/eccser/p/14386194.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有