首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >什么转账失败了? 那可能是「数据库事务」没有处理好

什么转账失败了? 那可能是「数据库事务」没有处理好

作者头像
阿凯
发布2018-06-29 12:31:20
1.1K0
发布2018-06-29 12:31:20
举报
文章被收录于专栏:程序员阿凯程序员阿凯

阅读文本大概需要 6 分钟。

中午和同事一起吃饭,饭后AA,可一直没收到同事转账,下班前提醒了她。同事说:早就给你转过去了啊,我的钱都扣了的。可是,你的账户上确实没有收到... 这事可能真不是你的同事想懒你这十几块钱,有可能是遇到数据库事务出了问题...

数据库事务

一个数据库事务通常包含了一个序列的对数据库的读/写操作。它的存在包含有以下两个目的:

  • 为数据库操作序列,提供了一个从失败中恢复到正常状态的方法,同时提供了数据库即使在异常状态下仍能保持一致性的方法。
  • 当多个应用程序在并发访问数据库时,可以在这些应用程序之间提供一个隔离方法,以防止彼此的操作互相干扰。

当事务被提交给了DBMS(数据库管理系统),则DBMS(数据库管理系统)需要确保该事务中的所有操作都成功完成且其结果被永久保存在数据库中,如果事务中有的操作没有成功完成,则事务中的所有操作都需要被回滚,回到事务执行前的状态;同时,该事务对数据库或者其他事务的执行无影响,所有的事务都好像在独立的运行

案例说明

老马给老王转1000块钱,这个过程涉及到两个数据库的操作: 1、先是从老马的账上扣除1000; 2、再在老王的账上加上1000。 如果这两次操作是独立的,那么有可能老马扣掉1000块钱之后,服务器异常,老王的帐上没有加上1000。 我们就希望这两次数据库的操作不是相互独立的,即处于同一事务。

数据库中的事务 是指逻辑上的一组操作,这组操作要么都执行成功,要么都不执行成功。

技术分析

2.1 事务的四大特性(ACID)

事务的四大特性分别是:

l原子性 (Atomicity):事务中所有操作是不可再分割的原子单位。事务中的所有操作要么全部执行成功,要么全部执行失败。

l一致性 (Consistency):事务执行后,数据库状态与其他业务规则保持一致。如转账业务,无论事务是否执行成功,参与转账的两个账号的余额之和应该保持不变。

l隔离性 (Isolation):在并发操作中,不同事务之间应该隔开,使每个并发中的事务不会相互干扰。

l持久性 (Durability):一旦事务提交成功,事务中所有的数据操作都必须持久化到数据库。即使提交事务后,数据库马上崩溃,在数据库重启的时候,也必须能保证通过某种机制恢复数据。

2.2 Mysql中开启和关闭事务

默认情况下,mysql每执行一条sql语句,都是一个单独的事务,如果需要在一个事务中包含多条sql语句,那么需要在执行sql之前开启事务.

l 开启事务:start transaction l 出现异常:rollback ( 回滚 ) l 关闭事务:commit ( 提交 )

在执行sql之前,先执行start transaction,这就开启了一个事务,然后可以去执行多条sql语句,最后要结束事务 commit 表示提交,即事务中的多条 sql 语句所做出的影响会持久化到数据库。或者通过 rollback 回滚,即回到事务起点,之前做的所有操作都将被取消。

以tom给jim转账为例进行演示:

  1. 查询所有人的余额
  1. 开启事务
  1. tom减去100块钱
  1. 查询余额
  1. 给jim加上100块钱
  1. 再次查询余额
  1. 回滚事务
  1. 再次查询余额

之前的操作全部取消了...

事务的隔离级别

如果我们不考虑事务的隔离性,当有多个线程在进行数据库操作的时候,会出现一些严重的问题.

3.1 事务的并发读问题

l脏读:读取到另一个事务未提交的数据

l不可重复读:对同一字段的两次读取 数据不一致。因为另一事务对该数据进行了修改(update)

l幻读(虚读):对同一张表的两次查询 记录不一致。因为另一个事务插入( insert )了一条数据

3.2 事务的四大隔离级别

为了防止并发读问题,mysql 有四种隔离级别。在相同的数据环境下,使用相同的输入,执行相同的工作,但隔离级别不同,可以导致不同的结果。

  1. Serializable:串行化

不会出现任何并发问题,因为它对同一数据的访问是串行的,而不是并发访问的.但是这种级别性能最差

  1. Repeatable Read:可重复读(Mysql 默认隔离基本)

防止脏读和不可重复读,会出现虚读。性能比Serializable好。

  1. Read Committed:读已提交数据(Oracle 默认隔离级别)

防止脏读,性能比Repeatable Read好.

  1. Read Uncommitted:提交未读数据

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-05-28,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 程序员阿凯 微信公众号,前往查看

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

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
数据库
云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档