grace-yan

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理
  3 随笔 :: 0 文章 :: 0 评论 :: 32 阅读

事务的定义


事务(Transaction)是一个逻辑上完整的操作序列,它包含了一组数据库操作命令。这些操作要么全部执行成功,要么全部不执行,以此来维护数据库的一致性和完整性。事务的主要目的是确保数据的准确性,即使在出现错误或系统故障时也是如此。
事务是一个原子操作。是一个最小执行单元。可以甶一个或多个SQL语句组成

事务的应用场景

  • 金融交易:银行转账是最典型的事务应用场景之一,确保从一个账户扣除金额的同时,另一账户能相应增加金额,且整个过程不会因故障中断而导致资金丢失或重复记账。
  • 库存管理:在线购物平台中,当用户下单购买商品时,系统需要确保库存减少和订单创建这两个操作作为一个整体执行,避免超卖或库存错误。
  • 航空订票系统:机票预订过程中,座位的锁定和付款的确认必须作为一个不可分割的事务处理,以防止座位被重复预订。
  • 酒店预订:确保房间预订和支付过程的完整性,避免房间被重复预定或支付后未保留房间的情况。

事务的四大特性

  • 原子性,Atomicty,也就是我们刚才说的不可再分,也就意味着我们对数据库的一系列的操作,要么都是成功,要么都是失败,不可能出现部分成功或者部分失败的情况。以转账的场景为例,一个账户的余额减少,对应一个账户的增加,这两个一定是同时成功或者同时失败的。
    全部成功比较简单,问题是如果前面一个操作已经成功了,后面的操作失败了,怎么让它全部失败呢?这个时候我们必须要回滚
    原子性,在 **InnoDB **里面是通过 undo log 来实现的,它记录了数据修改之前的值(逻辑日志),一旦发生异常,就可以用 undo log 来实现回滚操作。

  • 一致性(Consisent) 事务的一致性是指在数据库管理系统中,事务的执行应当保证从一个一致性的状态转变为另一个一致性的状态。具体来说,这要求在事务开始之前和结束之后,数据库都保持着某种定义好的完整性约束和业务规则,确保数据的准确性和可靠性。
    例一,现在,用户A要向用户B转账100元。这个操作需要保持数据库的一致性,具体步骤可以分为以下几个事务内的操作:
    1 开始事务:首先,数据库系统标记一个新事务的开始。
    2 检查余额:系统检查用户A的账户余额是否足够进行这次转账。如果用户A的余额小于100元,则事务应该被回滚,以保持账户余额的准确性(一致性)。
    3 扣款:如果用户A的余额足够,系统从用户A的账户中减去100元,并准备记录这一变化。
    4 存款:同时,系统给用户B的账户增加100元。
    5 记录交易:在Transactions表中添加一条新的交易记录,详细说明这次转账的信息。
    6 提交事务:所有上述操作完成后,如果没有发生任何错误(比如并发事务导致的冲突),事务被提交。这时,用户A的余额减少和用户B的余额增加以及交易记录的创建都永久地保存到数据库中,整个数据库状态保持一致,即账户的总金额没有因为这次转账而改变,只是在不同账户之间重新分配。
    7 事务失败处理:如果在执行上述任何一步骤时出现问题(比如系统崩溃),事务管理器会自动回滚事务,确保数据不被破坏,维持在事务开始前的一致状态。
    例二:所谓一致性,指的是数据处于一种有意义的状态,这种状态是语义上的而不是语法上的。最常见的例子是转帐。例如从帐户A转一笔钱到帐户B上,如果帐户A上的钱减少了,而帐户B上的钱却没有增加,那么我们认为此时数据处于不一致的状态。从这段话的理解来看,所谓一致性,即,从实际的业务逻辑上来说,最终结果是对的、是跟程序员的所期望的结果完全符合的

  • 隔离性(Isolation,又称独立性)数据库允许多个并发事务同时对其数据进行读写和修改的能力,隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致。事务隔离分为不同级别,包括读未提交(Read uncommitted)、读提交(read committed)、可重复读(repeatable read)和串行化(Serializable)。四个隔离等级是在事务的隔离性那块的内容。

  • 持久性,Durable,事务的持久性是什么意思呢?我们对数据库的任意的操作,增删改,只要事务提交成功,那么结果就是永久性的,不可能因为我们系统宕机或者重启了数据库的服务器,它又恢复到原来的状态了。这个就是事务的持久性。

事务的开启和提交

  • 自动开启和提交:执行这样一条更新语句的时候,它有事务吗?
    update student set name = '汤姆' where id=1;
    事实上,它自动开启了一个事务,并且提交了,所以最终写入了磁盘。
    这个是开启事务的第一种方式,自动开启和自动提交。
  • 手动开启提交:todo

事务并发带来的问题

有很多人同时去操作数据库的同一张表,A更新了第一条数据,B准备读第一条数据,那么B读到的数据应该是A修改之前的数据还是A修改之后的数据?

引申出来的三个问题

  • 脏读:当前事务(A)中可以读到其他事务(B)未提交的数据(脏数据),这种现象是脏读。举例如下(以账户余额表为例):
    image

  • 不可重复读:在事务A中先后两次读取同一个数据,两次读取的结果不一样,这种现象称为不可重复读。脏读与不可重复读的区别在于:前者读到的是其他事务未提交的数据,后者读到的是其他事务已提交的数据。举例如下:
    image

  • 幻读:在事务A中按照某个条件先后两次查询数据库,两次查询结果的条数不同,这种现象称为幻读。不可重复读与幻读的区别可以通俗的理解为:前者是数据变了,后者是数据的行数变了。举例如下:
    image

引申出数据库的隔离机制

SQL标准中定义了四种隔离级别,并规定了每种隔离级别下上述几个问题是否存在。一般来说,隔离级别越低,系统开销越低,可支持的并发越高,但隔离性也越差。隔离级别与读问题的关系如下:
image
在实际应用中,读未提交在并发时会导致很多问题,而性能相对于其他隔离级别提高却很有限,因此使用较少。可串行化强制事务串行,并发效率很低,只有当对数据一致性要求极高且可以接受没有并发时使用,因此使用也较少。因此在大多数数据库系统中,默认的隔离级别是读已提交(如Oracle)或可重复读(后文简称RR)。
InnoDB默认的隔离级别是RR,后文会重点介绍RR。需要注意的是,在SQL标准中,RR是无法避免幻读问题的但是InnoDB实现的RR避免了幻读问题。 具体文章链接https://www.cnblogs.com/cnndevelop/p/12088159.html todo

MySql锁机制 todo

MySql索引机制 todo

posted on   RedBlackme  阅读(24)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
点击右上角即可分享
微信分享提示