MySQL基础学习篇(5)——TPL

MySql基础学习

注明:文章笔记均来自哔哩哔哩视频学习

十一、事务【重点】

11.1 模拟转账

生活当中转账是转账方账户扣钱,收账方账户加钱。我们用数据库操作来模拟实现转账。

11.1.1 数据库模拟转账
#A账户转账给B账户1000元
#B账户减1000元

#新建账户表
CREATE TABLE t_account(
	account_id INT PRIMARY KEY,
	money INT
)CHARSET=utf8;
#插入数据
INSERT INTO t_account(account_id,money) VALUES(1,5000);
INSERT INTO t_account(account_id,money) VALUES(2,5000);
#模拟转账
UPDATE t_account SET money=money-1000 WHERE account_id=1;#转账
UPDATE t_account SET money=money+1000 WHERE account_id=2;#收账
  • 上述代码完成了两个账户之间转账的操作

11.1.2 模拟转账错误

UPDATE t_account SET money=money-1000 WHERE account_id=1;#转账
#断电,异常,出错...
UPDATE t_account SET money=money+1000 WHERE account_id=2;#收账
  • 上述代码在减操作后过程中出现了异常或加钱语句出错会发现减钱成功了而加钱失败了
  • 注意每条SQL语句都是一个独立的操作一个操作执行完对数据库是永久性的影响

11.2 事务的概念

事务是一个原子操作,是一个做小执行单元。可以由一个或多个SQL语句组成,在同一个事务当中,所有的SQL语句都成功执行,整个事务成功,有一个SQL语句执行失败,整个事务执行失败。

11.3 事务的边界

  • 开始:连接到数据库,执行一条DML语句。上一个事务结束后,又输入了一条DML语句,即事务的开始。
  • 结束:
    1. 提交:
      • 显式提交:COMMIT;
      • 隐式提交:一条创建、删除的语句,正常退出(客户端退出连接);
    2. 回滚:
      • 显式回滚:ROLLBACK;
      • 隐式回滚:非正常退出(断电、宕机),执行了创建、删除的语句,但是失败了,会为这个无效的语句执行回滚。

如11.1.2节中的两条语句就是两个事务,第一条语句执行便是事务的开始,分号便是事务的结束,执行完毕该语句就被提交了;而第二句由于执行失败,该语句的结果就是回滚,回到事务前的样子。

11.4 事务的原理

数据库会为每一个客户端都维护一个空间独立的缓存区(回滚段),一个事务中所有的增删改查语句的执行结果都会缓存在回滚段中,只有当事务中所有SQL语句均正常结束(COMMIT),才会将回滚段中的数据同步到数据库。否则无论因为哪种原因失败,整个事务将回滚(ROLLBACK)。

11.5 事务的特性(ACID)

  • Atomicity原子性

    表示一个事务内的所有操作是一个整体,要么全部成功,要么全部失败。

  • Consistency一致性

    表示一个事务内有一个操作失败时,所有更改过的数据都必须回滚到修改前状态。

  • Isolation隔离性

    事务查看数据库操作时数据所处的状态,要么是另一并发事务修改它之前的状态,要么是另一事物修改它之后的状态,事务不会查看中间状态的数据。

  • Durability持久性

    持久性事务完成之后,它对与系统的影响是永久性的。

11.6 事务应用

应用环境:基于增删改查语句的操作结果(均返回操作后受影响的行数),可通过程序逻辑手动控制事务提交或回滚。

11.6.1 事务完成转账

手动开启事务,将两个减钱和加钱的操作放到事务中,操作完之后再提交。

#开启事务
START TRANSACTION;
#执行减钱操作(两个账户初始钱都为5000)
UPDATE t_account SET money=money-1000 WHERE account_id = 1;
#执行加钱操作
UPDATE t_account SET money=money+1000 WHERE account_id = 2;
#查看该事务中账户数据
SELECT * FROM t_account;

以上SQL语句开启了事务,但并未进行提交,此时查看账户中的数据如下:

account_idmoney
14000
26000

发现数据已经变了,但该数据只是事务的中间状态。

然后在你的数据库管理系统中新建一个连接,新建连接名随便取一个,然后新建查询。这么做相当于模拟了另外一个客户端:

执行SELECT * FROM t_account;,发现表中的数据并没有改变

account_idmoney
15000
25000

这是因为在第一个连接中开启了事务,但没有提交;而在another连接中,查询语句也是一个事务(没有显式开启和显式提交),该事务只能查看其它事务修改前后者修改后的状态,此处就是只能查看转账操作提交前的状态,两个账户都是5000,这也是事务的隔离性

回到localhost连接中,提交事务;然后在another连接中再查询一次:

#localhost连接,提交事务
COMMIT;
#another连接,查询表
SELECT * FROM t_account;

此时的查询结果如下:

account_idmoney
14000
26000

发现数据已经正式修改完毕。

回滚操作类似,但它是取消掉事务的操作,回到事务前的状态。比如事务开启后,减钱成功,但是加钱失败了(可以用SQL语句某个单词写错来模拟),然后手动执行ROLLBACK,减钱操作就会被撤销。不再演示。

  • 此处的演示是手动进行了事物的开启和提交/回滚,在写程序时,这些操作都会在程序中进行控制。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值