MySQL(高级特性篇) 13 章——事务基础知识

一、数据库事务概述

++事务++是数据库区别于文件系统的重要特性之一

(1)存储引擎支持情况

  1. ++SHOW ENGINES++命令来查看当前MySQL支持的存储引擎都有哪些,以及这些存储引擎是否支持事务
  2. 能看出++在MySQL中,只有InnoDB是支持事务的++

(2)基本概念

  1. 事务:一组逻辑操作单元,使数据从一种状态变换到另一种状态
  2. 事务处理的原则 :保证所有事务都作为一个工作单元来执行。当在一个事务中执行多个操作时(1)要么所有的修改都被提交(commit ),那么这些修改就永久 地保存下来(2)要么数据库管理系统放弃 所作的所有修改 ,整个事务回滚(rollback)到最初状态

(3)事务的ACID特性

1.3.1原子性

原子性 :事务是一个不可分割的工作单位,要么全部提交,要么全部失败回滚,不存在中间的状态

1.3.2一致性

  1. 一致性 :事务执行前后,数据从一个合法性状态 变换到另一个合法性状态
  2. 合法的数据状态 :满足预定的约束的状态就叫做合法的状态
  3. 举例1:A账户有200元,转账300元出去,此时A账户余额为-100元。你自然就发现了此时数据是不一致的,为什么呢?++因为你定义了一个状态++,余额这列必须>=0
  4. 举例2:A账户200元。转账50元给B账户,A账户的钱扣了,但是B账户因为各种意外,余额并没有增加。你也知道此时数据是不一致的,为什么呢?++因为你定义了一个状态++,要求A+E的总余额必须不变
  5. 举例3:在数据表中将姓名字段设置为唯一性约束,这时当事务进行提交或者事务发生回滚的时候,如果数据表中的姓名不唯一,就破坏了事务的一致性要求

1.3.3隔离性

  1. 隔离性 :即并发执行的各个事务之间不能相互干扰

  2. 如果无法保证隔离性会怎么样?假设A账户有200元,B账户0元。A账户往B账户转账两次,每次金额为50元,分别在两个事务中执行。如果无法保证隔离性,会出现下面的情形:

    sql 复制代码
    UPDATE accounts SET money = money - 50 WHERE NAME = 'AA';
    UPDATE accounts SET money = money + 50 WHERE NAME = 'BB';

1.3.4持久性

  1. 持久性 :一个事务一旦被提交,它对数据库中数据的改变就是永久性的

  2. 持久性是通过事务日志 来保证的。日志包括了重做日志 和**回滚日志。**当我们通过事务对数据进行修改的时候,(1)首先会将数据库的变化信息记录到重做日志中,(2)然后再对数据库中对应的行进行修改

  3. 这样做的好处是:即使数据库系统崩溃,也能找到重做日志,重新执行,从而使事务具有持久性

事务 :++把需要保证++++原子性++++、++++隔离性++++、++++一致性++++和++++持久性++++的一组数据库操作称为一个事务++

(4)事务的状态

事务对应着一个或多个数据库操作,MySQL++根据这些操作所执行的不同阶段++把事务大致划分成几个状态:

  1. 活动的active ):事务对应的数据库操作正在执行过程中时,我们就说该事务处在活动的状态
  2. 部分提交的partially committed ):当事务中的最后一个操作执行完成,但由于++操作都在内存中执行++,所造成的影响并没有刷新到磁盘时,我们就说该事务处在部分提交的状态
  3. 失败的failed ):当事务处在活动的或者部分提交的 状态时,可能遇到了某些错误(数据库自身的错误、操作系统错误或者直接断电等)而无法继续执行,或者人为地停止当前事务的执行,我们就说该事务处在失败的状态
  4. 中止的aborted ):如果事务执行了一部分而变为失败的状态,那么就需要把已经修改的事务中的操作还原到事务执行前的状态。我们把这个过程称之为回滚。当回滚操作执行完毕时,我们就说该事务处在了中止的状态
  5. 提交的committed ):当处在一个部分提交状态的事务,将修改过的数据都同步到磁盘上之后,我们就可以说事务处在了提交的状态

一个基本的状态转换图如下所示:

图中可见:只有当事务处于提交的(刷新到磁盘) 或者中止的(回滚操作执行完) 状态时,++一个事务的生命周期才算是结束了++

二、如何使用事务

使用事务有两种方式,分别为显式事务和隐式事务

事务的完成过程

  1. 步骤一:开启事务
  2. 步骤二:一系列的DML操作
  3. ......
  4. 步骤三:事务结束的状态:提交的状态(COMMIT) 、 中止的状态(ROLLBACK)

(1)显式事务

  1. 步骤一:显式开启一个事务

    1. SQL语句:

      sql 复制代码
      BEGIN;
      #或者
      START TRANSACTION;
    2. ++START TRANSACTION++语句相较于BEGIN特别之处在于,++后面能跟随几个修饰符++ ① 修饰符 :READ ONLY。标识当前事务是一个只读事务 ,也就是属于该事务的数据库操作只能读取数据,而不能修改数据(只读事务中只是不允许修改那些其他事务也能访问到的表中的数据,++对于临时表来说(使用CREATE TMEPORARY TABLE创建的表),由于它们只能在当前会话中可见,所以只读事务其实也是可以对临时表进行增、删、改操作的++) ② 修饰符 :READ WRITE。标识当前事务是一个读写事务 ,也就是属于该事务的数据库操作++既可以读取数据,也可以修改数据++ ③ 修饰符 :WITH CONSISTENT SNAPSHOT。启动一致性读

    3. 比如:

      sql 复制代码
      START TRANSACTION READ ONLY;#开启一个只读事务
      START TRANSACTION READ ONLY,WITH CONSISTENT SNAPSHOT;#开启只读事多和一致性读
      START TRANSACTION READ WRITE,WITH CONSISTENT SNAPSHOT;#开启读写事务和一致性读
    4. 注意(1)READ ONLY和READ WRITE是用来设置所谓的++事务访问模式++的,就是以只读还是读写的方式来访问数据库中的数据,一个事务的访问模式不能同时既设置为只读的又设置为读写的(2)++如果不显式++指定事务的访问模式,++那么该事务的访问模式就是读写模式++

  2. 步骤二:一系列事务中的操作(主要是DML,不含DDL

  3. 步骤三:提交事务或中止事务(即回滚事务)

    sql 复制代码
    # 提交事务。当提交事务后,对数据库的修改是永久性的
    COMMIT;
    # 回滚事务。即撤销正在进行的所有没有提交的修改
    ROLLBACK;
    # 将事务回滚到某个保存点
    ROLLBACK TO [SAVEPOINT];
  4. 其中关于SAVEPOINT(保存点)相关的操作有:

    sql 复制代码
    #在事务中创建保存点,方便后续针对保存点进行回滚。一个事务中可以存在多个保存点
    SAVEPOINT 保存点名称;
    #删除某个保存点
    RELEASE SAVEPOINT 保存点名称;

(2)隐式事务

  1. MySQL中有一个系统变量autocommit
  2. autocommit默认是ON。此时++每一个DML都是一个独立的事务++
  3. 如果想关闭这种自动提交 的功能:
    1. 方式一:针对于DML操作是有效的,对DDL操作是无效的

      sql 复制代码
      SET autocommit = OFF;
      #或
      SET autocommit = 0;
      #或
      SET autocommit = FALSE;
    2. 方式二:++我们在autocommit为ON(TRUE/1)的情况下,使用start transaction或begin开启事务,则DML操作就不会自动提交数据++

  4. 补充Oracle默认不自动提交 ,需要手写COMMIT命令,而MySQL 默认自动提交

(3)隐式提交数据的情况

  1. 数据定义语言(Data Definition Language,缩写为DDL) :数据库对象,指的就是数据库、表、视图、存储过程等结构。当使用CREATE、ALTER、DROP等语句去修改数据库对象 时,就会隐式的提交前边语句所属于的事务。即:

    sql 复制代码
    BEGIN;
    SELECT ... #事务中的一条语句
    UPDATE ...#事务中的一条语句
    ...  #事务中的其它语句
    CREATE TABLE ...# 此语句会隐式的提交前边语句所属于的事务
  2. 隐式使用或修改mysql数据库中的表(DCL):当使用ALTER USER、CREATE USER、DROP USER 、RENAME USER、GRANT、REVOKE、SET PASSWORD等语句时也会隐式的提交前边语句所属于的事务

  3. (1) 当在一个事务还没提交或者回滚时就又使用START TRANSACTION或者BEGIN语句++开启了另一个事务++时,会隐式的提交上---个事务**(2)** 当前的autocommit系统变量的值为OFF,我们++手动把它调为ON时,也会隐式的提交前边语句所属的事务++(3) 使用LOCK TABLES、UNLOCK TABLES等++关于锁定的语句++也会隐式的提交前边语句所属的事务

  4. 加载数据的语句 :使用++LOAD DATA++语句来批量往数据库中导入数据时,也会隐式的提交前边语句所属的事务

  5. 关于MySQL复制的一些语句 :使用START SLAVE、STOP SLAVE、RESET SLAVE、CHANGE MASTER TO等语句时会隐式的提交前边语句所属的事务(主从复制

  6. 其它的一些语句 :使用ANALYZE TABLE、CACHE INDEX、CHECK TABLE、FLUSH、LOAD INDEX INTO CACHE、0PTIMIZE TABLE、REPAIR TABLE、RESET等语句也会隐式的提交前边语句所属的事务

  7. 总结:autocommit只对DML有用,对DDL和DCL都不起作用

(4)使用举例1:提交与回滚

  1. 测试代码:

    sql 复制代码
    # 案例分析
    #SET autocommit = TRUE; 
    #SHOW VARIABLES LIKE 'autocommit';
    #举例1: commit 和 rollback
    
    USE atguigudb2;
    #情况1:
    CREATE TABLE user3(NAME VARCHAR(15) PRIMARY KEY);
    
    SELECT * FROM user3;
    
    BEGIN;
    INSERT INTO user3 VALUES('张三'); #此时不会自动提交数据
    COMMIT;
    
    BEGIN; #开启一个新的事务
    INSERT INTO user3 VALUES('李四'); #此时不会自动提交数据
    INSERT INTO user3 VALUES('李四'); #受主键的影响,不能添加成功
    ROLLBACK;
    
    SELECT * FROM user3;
    
    #情况2:
    TRUNCATE TABLE user3;  #DDL操作会自动提交数据,不受autocommit变量的影响。
    
    SELECT * FROM user3;
    
    BEGIN;
    INSERT INTO user3 VALUES('张三'); #此时不会自动提交数据
    COMMIT;
    
    INSERT INTO user3 VALUES('李四');# 默认情况下(即autocommit为true),DML操作也会自动提交数据。
    INSERT INTO user3 VALUES('李四'); #事务的失败的状态
    
    ROLLBACK;
    
    SELECT * FROM user3;
    
    #情况3:
    TRUNCATE TABLE user3;
    
    SELECT * FROM user3;
    
    SELECT @@completion_type;#默认值是NO_CHAIN,即0
    
    SET @@completion_type = 1;
    
    BEGIN;
    INSERT INTO user3 VALUES('张三'); 
    COMMIT;
    
    
    SELECT * FROM user3;
    
    INSERT INTO user3 VALUES('李四');
    INSERT INTO user3 VALUES('李四'); 
    
    ROLLBACK;
    
    
    SELECT * FROM user3;
  2. MySQL中completion_type参数的作用,实际上这个参数有3种可能:

    1. completion=0,这是默认情况 。当执行COMNIT的时候会提交事务,++在执行下一个事务时,还需要使START TRANSACTION 或者BEGIN来开启++
    2. completion=1,这种情况下,当提交事务后,相当于执行了COMMIT AND CHAIN,也就是开启一个链式事务,即++提交事务之后会开启一个相同隔离级别的事务++
    3. completion=2,这种情况下,当提交事务后,相当于执行了COMMIT AND RELEASE,也就是++提交后,会自动与服务器断开连接++
  3. 注意

    1. 当我们设置autocommit=0时,每一个DML都是一个独立的事务,和事务一样都需要COMMIT/ROLLBACK
    2. 当我们设置autocommit=1时,每一个DML都会自动提交,但事务需要COMMIT/ROLLBACK
    3. 我们谈到的事务基本都是显式事务。所谓的隐式事务,就是每一个DML(根据autocommit的值来判断是否会自动提交)

(5)使用举例2:测试不支持事务的engine

  1. 测试代码:

    sql 复制代码
    #举例2:体会INNODB 和 MyISAM
    
    CREATE TABLE test1(i INT) ENGINE = INNODB;
    
    CREATE TABLE test2(i INT) ENGINE = MYISAM;
    
    #针对于innodb表
    BEGIN;
    INSERT INTO test1 VALUES (1);
    ROLLBACK;
    
    SELECT * FROM test1;
    
    
    #针对于myisam表:不支持事务
    BEGIN;
    INSERT INTO test2 VALUES (1);
    ROLLBACK;
    
    SELECT * FROM test2;

(6)使用举例3:SAVEPOINT

  1. 测试代码:

    sql 复制代码
    #举例3:体会savepoint
    
    CREATE TABLE user3(NAME VARCHAR(15),balance DECIMAL(10,2));
    
    show variables like "autocommit";
    set autocommit = 0;
    truncate table user3;
    
    BEGIN;
    INSERT INTO user3(NAME,balance) VALUES('张三',1000);
    COMMIT;
    
    SELECT * FROM user3;
    
    BEGIN;
    UPDATE user3 SET balance = balance - 100 WHERE NAME = '张三';
    
    UPDATE user3 SET balance = balance - 100 WHERE NAME = '张三';
    
    SAVEPOINT s1;#设置保存点
    
    UPDATE user3 SET balance = balance + 1 WHERE NAME = '张三';
    
    ROLLBACK TO s1; #回滚到保存点
    
    
    SELECT * FROM user3;
    
    ROLLBACK; #回滚操作
    
    SELECT * FROM user3;
  2. 注意

    1. COMMIT是把在内存中修改好的数据刷新到磁盘上 ,ROLLBACK可以理解成:是把硬盘中相应的数据恢复到事务开始之前的状态
    2. COMMIT和ROLLBACK都是代表事务的结束

三、事务隔离级别

MySQL是一个客户端/服务器架构的软件。对于同一个服务器来说,可以有若干个客户端与之连接,每个客户端与服务器连接上之后,就可以称为一个会话(session )。每个客户端都可以在自己的会话中向服务器发出请求语句,一个请求语句可能是某个事务的一部分,也就是++服务器来说可能同时处理多个事务++。事务具有隔离性 的特性,理论上在某个事务对某个数据进行访问 的时候,其他事务应该排队,当该事务提交之后,其它事务才可以继续访问这个数据。但是这样对性能影响太大,我们既想保持事务的隔离性,又想让服务器在处理访问统一数据的多个事务时,性能尽量高些 ,那就看二者如何权衡取舍了

(1)数据准备

  1. 创建一个表:

    sql 复制代码
    CREATE TABLE student (
    studentno INT,
    name VARCHAR(20),
    class varchar(20),
    PRIMARY KEY (studentno)
    ) Engine=InnoDB CHARSET=utf8;
  2. 然后向这个表里插入一条数据:

    sql 复制代码
    INSERT INTO student VALUES(1, '小谷', '1班');
  3. 现在表里的数据就是这样的

    sql 复制代码
    select * from student;

(2)数据并发问题

事务的隔离性和并发性如何取舍:先看一下访问相同数据的事务不保证串行 (++也就是执行完一个再执行另一个++)执行 的情况下(也即,并发)可能出现哪些问题

3.2.1脏写(Dirty Write)

  1. 对于两个事务Session A、Session B,如果事务Session A修改了另一个未提交的事务Session B修改过的数据,那就意味着发生了脏写(两个并发事务,一个事务导致另一个事务对数据的修改丢失了。也即,写的东西丢了)
  2. (1)Session A和Session B各自开启了一个事务,(2)Session B中的事务先将studentno列为1的记录的name字段更新为"李四",然后Session A中的事务接着又把这条studentno列为1的记录的name列更新为"张三"。(3)如果之后Session B中的事务进行了回滚,那么Session A中的更新也将不复存在 ,这种现象就称之为脏写。这时Session A中的事务就没有效果了,明明把数据更新了,最后也提交事务了,最后看到的数据什么变化也没有

3.2.2脏读(Dirty Read)

  1. 对于两个事务Session A、Session B,Session A读取了已经被SessionB更新但还没有被提交的字段。之后若Session B回滚,Session A读取的内容就是临时且无效的(两个并发事务,一个事务读到了另一个事务中会丢失的修改。也即,读到了不存在的东西)
  2. (1)Session A和Session B各开启了一个事务,(2)Session B中的事务先将studentno列为1的记录的name列更新为"张三",(3)然后Session A中的事务再去查询这条studentno为1的记录,如果读到列name的值为"张三",(4)而Session B中的事务稍后进行了回滚,那么Session A中的事务相当于读到了一个不存在的数据 ,这种现象就称之为脏读

3.2.3不可重复读**(Non-Repeatable Read)**

  1. 对于两个事务Session A、Session B,Session A 读取了一个字段,然后Session B更新了该字段。之后Session A再次读取同一个字段,值就不同 了。那就意味着发生了不可重复读
  2. 此时,在Session B中提交了几个隐式事务(注意是隐式事务,意味着语句结束事务就提交了),这些事务都修改了studentno列为1的记录的列name的值,每次事务提交之后,如果Session A中的事务都可以查看到最新的值,这种现象也被称之为不可重复读

3.2.4幻读(Phantom)

  1. 对于两个事务Session A、Session B,Session A 从一个表中读取了一个字段,然后 Session B 在该表中插入了一些新的行。之后,如果 Session A 再次读取同一个表,就会多出几行 。那就意味着发生了幻读

  2. (1)Session A中的事务先根据条件studentno > 0这个条件查询表student,得到了name列值为'张三'的记录;(2)之后Session B中提交了一个隐式事务,该事务向表student中插入了一条新记录;(3)之后Session A中的事务再根据相同的条件studentno > 0查询表student,得到的结果集中包含Session B中的事务新插入的那条记录 ,这种现象也被称之为幻读 。我们把++新插入的那些记录称之为幻影记录++

  3. 注意1 :如果Session B中删除了 一些符合studentno > 0的记录而不是插入新记录,那SessionA之后再根据studentno > 0的条件读取的记录变少了 ,这种现象不属于幻读幻读强调的是一个事务按照某个相同条件多次读取记录时,++后读取时读到了之前没有读到的记录++

  4. 注意2 :那对于先前已经读到的记录,之后又读取不到这种情况,算啥呢?这相当于对每一条记录都发生了不可重复读的现象。幻读只是重点强调了读取到了之前读取没有获取到的记录

(3)SQL中的四种隔离级别

  1. 按严重性排序:脏写>脏读>不可重复读>幻读
  2. 隔离级别越低,并发问题发生的就越多。SQL标准中设立了4个隔离级别(++这四个都解决了脏写的问题++):
    1. READ UNCOMMITTED :读未提交,在该隔离级别,所有事务都可以看到其他++未提交++事务的执行结果。++不能避免脏读、不可重复读、幻读++
    2. READ COMMITTED :读已提交,它满足了隔离的简单定义:一个事务++只能看见已经提交++事务所做的改变。这是大多数数据库系统的默认隔离级别(但不是MySQL默认的) 。可以避免脏读,但++不可重复读、幻读问题仍然存在++
    3. REPEATABLE READ :可重复读,事务A在读到一条数据之后,此时事务B对该数据进行了修改并提交,那么事务A再读该数据,++读到的还是原来的内容++。可以避免脏读、不可重复读,但++幻读问题仍然存在++ 。这是MySQL的默认隔离级别
    4. SERIALIZABLE :可串行化,确保事务可以从一个表中读取相同的行。在这个事务持续期间,禁止其他事务对该表执行插入、更新和删除操作。所有的并发问题都可以避免,但性能十分低下
  3. ++隔离级别越高,数据库的并发性能就越差++,4种事务隔离级别与并发性能的关系如下:

(4)MySQL支持的四种隔离级别

  1. 不同的数据库厂商对SQL标准中规定的四种隔离级别支持不一样。比如,Oracle就只支持READ COMMITTED(默认隔离级别)和SERIALIZABLE隔离级别。MySQL虽然支持4种隔离级别 ,但++MySQL在REPEATABLE READ隔离级别下,是可以禁止幻读问题的发生的++(看16章)

  2. MySQL的默认隔离级别为REPEATABLE READ,查看事务的隔离级别:

    sql 复制代码
    # 查看隔离级别,MySQL 5.7.20的版本之前:
    SHOW VARIABLES LIKE 'tx_isolation';
    
    # 查看隔离级别,MySQL 5.7.20的版本及之后:
    SHOW VARIABLES LIKE 'transaction_isolation';
    
    #或者不同MySQL版本中都可以使用的:
    SELECT @@transaction_isolation;

(5)如何设置事务的隔离级别

  1. 通过下面的语句修改事务的隔离级别 (两种方式):

    sql 复制代码
    SET [GLOBAL|SESSION] TRANSACTION ISOLATION LEVEL 隔离级别;
    #其中,隔离级别格式:
    > READ UNCOMMITTED
    > READ COMMITTED
    > REPEATABLE READ
    > SERIALIZABLE
    
    SET [GLOBAL|SESSION] TRANSACTION_ISOLATION = '隔离级别'
    #其中,隔离级别格式:
    > READ-UNCOMMITTED
    > READ-COMMITTED
    > REPEATABLE-READ
    > SERIALIZABLE
  2. 关于设置时使用GLOBAL或SESSION的影响:

    1. 使用GLOBAL 关键字(在全局范围影响):
    2. 使用SESSION关键字(在会话范围影响):

(6)不同隔离级别举例

  1. 初始化数据:

    sql 复制代码
    create table account(
    	id int primary key auto_increment,
        name varchar(15),
        balance decimal(10,2)
    );
    TRUNCATE TABLE account;
    
    INSERT INTO account VALUES (1, '张三','100 '),(2,'李四','0');
  2. 表中数据如下:

    sql 复制代码
    SELECT * FROM account;
  3. 演示1:

    1. 读未提交之脏读 设置隔离级别为未提交读:
    2. 事务1和事务2的执行流程如下:
  4. 演示2:

    1. 读已提交
    2. 设置隔离级别为可重复读,事务的执行流程如下:
  5. 演示4:幻读

四、事务的常见分类

  1. 从理论的角度,可以把事务分为以下几种类型:

    1. 扁平事务(Flat Transactions)

    2. 带有保存点的扁平事务(Flat Transactions with Savepoints)

    3. 链事务(Chained Transactions)

    4. 嵌套事务(Nested Transactions)

    5. 分布式事务(Distributed Transactions)

  2. 下面分别介绍这几种类型:

    1. 扁平事务:(1)++事务类型中最简单的一种++,但是实际生产环境中,++使用最频繁的事务++,故每个数据库系统都实现了对扁平事务的支持。在扁平事务中,所有操作都处于同一层次,其由BEGIN开始,++由COMMIT或ROLLBACK结束++,其间的操作是++原子的++,要么都执行,要么都回滚。扁平事务的主要限制是 ++不能提交或者回滚事务的某一部分++(2)扁平事务一般有三种不同的结果 ① 事务成功完成 ② 应用程序要求停止事务。比如应用程序在捕获到异常时会回滚 事务 ③ 外界因素强制终止事务。如++连接超时或连接断开++
    2. 带有保存点的扁平事务:(1)除了支持扁平事务支持的操作外,还允许在事务执行过程中++回滚到同一事务中较早的一个状态++。这是因为某些事务可能在执行过程中出现的错误并不会导致所有的操作都无效,放弃整个事务不合乎要求,开销太大(2)对于扁平的事务 来说,隐式的设置了一个保存点(在整个事务中,只有这一个保存点,因此,回滚只能会滚到事务开始时的状态)
    3. 链事务:(1)链事务是指++一个事务由多个子事务链式组成++,它可以被视为保存点模式的一个变种 。带有保存点的扁平事务,当发生系统崩溃时,所有的保存点都将消失,这意味着当进行恢复时,事务需要从开始处重新执行,而不能从最近的一个保存点继续执行(2)链事务的思想是 :++在提交一个事务时,释放不需要的数据对象,将必要的处理上下文隐式地传给下一个要开始的事务,前一个子事务的提交操作和下一个子事务的开始操作合并成一个原子操作,这意味着下一个事务将看到上一个事务的结果,就好像在一个事务中进行一样。这样,在提交子事务时就可以释放不需要的数据对象,而不必等到整个事务完成后才释放++ (3)其工作方式如下:
    4. 嵌套事务:由一个顶层事务 (Top-Level Transaction)控制着各个层次的事务,顶层事务之下嵌套的事务被称为子事务 (Subtransaction),其控制着每一个局部的变换,++子事务本身也可以是嵌套事务++ 。因此,++嵌套事务的层次结构可以看成是一棵树++
    5. 分布式事务:通常是在一个分布式环境 下运行的扁平事务,因此,需要++根据数据所在位置访问网络中不同节点的数据库资源++ 。例如,一个银行用户从招商银行的账户向工商银行的账户转账1000元,这里需要用到分布式事务,因为不能仅调用某一家银行的数据库就完成任务
  3. 链事务与带有保存点的扁平事务的不同之处体现在:

    1. 带有保存点的扁平事务能回滚到任意正确的保存点,而链事务中只能恢复到最近的一个保存点
    2. 对于锁的处理,两者也不相同,链事务在执行COMMIT后即释放了当前所持有的锁,而带有保存点的扁平事务不影响迄今为止所持有的锁
相关推荐
八股文领域大手子16 分钟前
深入理解缓存淘汰策略:LRU 与 LFU 算法详解及 Java 实现
java·数据库·算法·缓存·mybatis·哈希算法
noravinsc34 分钟前
django admin 中更新表数据 之后再将数据返回管理界面
数据库·django·sqlite
Bruce-li__2 小时前
DRF凭什么更高效?Django原生API与DRF框架开发对比解析
数据库·django·sqlite
郭不耐3 小时前
PostgreSQL与MySQL哪个适合做时空数据分析?
mysql·postgresql·数据分析
noravinsc3 小时前
connection.cursor() 与 models.objects.filter
数据库·django·原生查询·orm查询
YH.4 小时前
MySQL 主从复制
mysql
laimaxgg5 小时前
MySQL复合查询
数据库·mysql
洞窝技术5 小时前
MYSQL:关于索引你想知道的
后端·mysql
编程在手天下我有5 小时前
Redis 常见问题深度剖析与全方位解决方案指南
数据库·redis·缓存·性能优化·数据持久化·分布式系统
辰哥单片机设计6 小时前
JQ6500语音模块详解(STM32)
数据库·mongodb