美文网首页
数据库事务详解

数据库事务详解

作者: 末池桑 | 来源:发表于2020-03-11 17:58 被阅读0次

事务概念

事务在数据库里是很重要的概念,指的是用户定义的一组不可分割的数据库操作序列,这组操作要么全执行,要么全失败回滚,保证了数据操作前后持一致性。以 JDBC 操作数据库中的转账汇款为例,在没开启事务的情况下,假设 xm、xh各有 1000 块钱,总共 2000 块钱,当 xm 向 xh 汇款 100 块钱时,执行如下图的方法:

xm 账户先是减去了相应的 100 ,但是由于 /by zero 异常,xh 账户上却没有加上相应的 100,此时就是丢掉了数据前后的一致性,因为当上图 transfer 方法执行后,xm 还有 900,xh 还是 1000 块钱,总共 1900 块钱,与刚开始 xm、xh 共持有的钱 2000 不符,也就是 xm 平白无故的就消失了 100 块钱,这个要是在现实生活中换做谁都是接收不了的。

而事务开启后,上图中这两条 sql 语句将会变成一荣俱荣,一损俱损的状态(原子性),只要事务还没提交,即使发生了 /by zero 错误,xm 减去 100 的那条 sql 语句就会被回滚,xm 最终还是 1000 块钱,从而保证了 xm、xh 所持有总钱数的一致性。

四大特性(ACID)

  • 原子性(Atomicity)
    讲白了就是用户定义的 多条 sql 语句 是一个整体,要么全部执行,要么全部不执行。
  • 一致性(Consistency)
    事务执行的结果必须是使数据库从一个一致性状态变到另一个一致性状态,就像上面说的转完钱后 xm、xh 持有的总钱数应保持不变。
  • 隔离性(Isolation )
    多个事务并发访问数据时,事务之间是隔离的,相互之间不会存在影响。数据库设立了有不同的隔离级别,MySQL 有四个隔离级别:Read uncommitted 、Read committed 、Repeatable read (默认)、Serializable ,详细后面分析。
  • 持久性(Durability)
    只要事务提交,数据就会被保存至数据库并保证永不丢失。也就是从内存里保存到了磁盘里,即使是数据库宕机崩溃、断电,数据都不会丢失。

事务并发问题

当多个事务并发访问数据时,若不对并发操作加以控制的话,就可能会造成查询和更新到不正确的数据,破坏事务前后的一致性,发生脏读、不可重复读、虚读。

    1. 脏读(dirty read)
      一个事务读取到了另一个事务未提交时修改的数据。解析图如下:

事务 B 先查询了 xm 的 money,接着事务 A 修改了 xm 的 money ,A 并没有提交事务,事务 B 再次查询 xm 的 money 时就变为了事务 A 修改后的内容了,这个就是脏读。

    1. 不可重复读(unrepeatable read)
      一个事务读取到了另一个事务提交后的数据。解析图如下:

意思是指:事务 A 在 update 一行数据的时候,事务 B 在其 update 前后都访问了这行数据,导致事务 B 两次查询这行数据时结果不一致。注:这里是指 update 一行数据,与幻读中的 insert 数据不同。

    1. 幻读/虚读(phantom read)
      一个事务读书到了另一个事务提交后的数据,解析图如下:

这个和不可重复读的概念很像,在事务 B insert 一行数据时,事务 A 在 insert 之前查了两次表中所有数据,导致两次结果集不一致,第二次查询时多了一条事务 B insert 的数据。注:这里是指 insert 一行数据,与幻读中的 update 数据不同。

MySQL 事务隔离级别

事务隔离级别是事务并发控制的整体解决方案,它通过锁机制来实现的,MySQL 有四个隔离级别,通过设置相应隔离级别可以防止脏读、不可重复读、幻读。

  • Read uncommitted 读未提交
    可以读取未提交的记录,会出现脏读,幻读,不可重复读,所有并发问题都可能遇到。
  • Read committed 读已提交
    事务中只能读到已提交的修改,不会出现脏读现象,但是会出现幻读,不可重复读。
  • Repeatable read 可重复读
    解决了不可重复读问题,但是任然存在幻读问题,MySQL InnoDb 默认的隔离级别。
  • Serializable 序列化
    最强级别的事务隔离,解决脏读、不可重复读、幻读问题,但是开启后会拖慢数据库并发效率,性能最低。

MySQL 查看隔离级别: select @@session.tx_isolation, @@global.tx_isolation; (session / local 为会话变量,global 为全局变量)
MySQL 设置隔离级别:set @@session.tx_isolation = 0/1/2/3;(0~3 分别表示:Read uncommitted 、Read committed、Repeatable read 、Serializable)

相关文章

  • Spring事务的详解

    数据库事务原理详解 1.事务的基本概念   事务(Transaction)是访问并可能更新数据库中各种数据项的一个...

  • Spring相关面试题:谈一谈你对事务的理解?

    事务详解 2. 事务管理 2.1 回顾事务 什么是事务? 在数据库开发中,一组业务逻辑操作,要么全部成功,要么全部...

  • Net Core中数据库事务隔离详解——以Dapper和Mysq

    Net Core中数据库事务隔离详解——以Dapper和Mysql为例事务隔离级别准备工作Read uncommi...

  • Spring之事务管理

    Spring事务管理(详解+实例)Spring详解(八)------事务管理 一. 概念 事务(Transacti...

  • 数据库事务详解

    概述 事务(Transaction)是由一系列对系统中数据进行访问与更新的操作所组成的一个程序执行逻辑单元。 AC...

  • 数据库-事务详解

    事务拥有四大特性 原子性一致性隔离性持久性 原子性事务中的所有动作要么全部提交成功,要么全部失败回滚(回滚是反向操...

  • 数据库事务详解

    一,什么是数据库事务? 简单来说,数据库事务(简称事务),是指一组数据操作,表现为一组SQL语句。要么全部执行成功...

  • 数据库事务详解

    概述 事务(Transaction)是由一系列对系统中数据进行访问与更新的操作所组成的一个程序执行逻辑单元。 AC...

  • 数据库事务详解

    事务概念 事务在数据库里是很重要的概念,指的是用户定义的一组不可分割的数据库操作序列,这组操作要么全执行,要么全失...

  • 数据库事务详解

    事务的产生是为了简化我们的编程模型,使我们在开发的过程中不用考虑各种潜在的错误和并发问题,而不是伴随着数据库系统天...

网友评论

      本文标题:数据库事务详解

      本文链接:https://www.haomeiwen.com/subject/lhzfjhtx.html