Advertisement

MySQL学习Day26——事务基础知识

阅读量:

一、数据库事务概述:

在数据库体系中,事务被视为区别其特性的关键要素之一。通过实施事务操作,数据库能够维持数据的一致性状态。当发生故障时,在特定时间点之后的数据状态可以通过回滚机制得到恢复。确保任何一次提交至数据库的操作在系统出现故障时仍能成功保存。

1.查看引擎支持事务的情况: 只有InnoDB存储引擎支持事务

复制代码
    SHOW ENGINES;

2.基本概念:

事务: 一组逻辑操作单元,使数据从一种状态变换到另一种状态

事务处理的原则: 为了确保所有操作被视为一个整体单位进行处理,在出现故障的情况下也不会更改这一处理方式。当在同一事务内进行多个操作时,则有两种可能的结果:要么所有操作都被提交(通过commit指令),从而永久地保存修改;否则系统会放弃所有所做的修改并回滚至最初状态。

3.事务的ACID特性:

Atomicity (atomicity): Atomicity refers to a transaction being an indivisible unit of work, either fully committed or entirely rolled back, without any intermediate states.

(2)一致性(consistency): 数据的一致性体现在事务处理过程中,在保证数据从合法状态转换到另一个合法状态下,并与具体的业务需求密切相关。其中的合法状态指的是满足预先设定约束条件下的数据状况。

(3)隔离性(isolation): 隔离性是指一个数据库系统中一个事务的执行不受其他事物的影响,在逻辑上与其它所有事物保持相互独立的一种特性。即在一个数据库系统中进行并发操作时,在逻辑层面上保证每个单独的操作都能按照自身的计划得到正确的处理,并且与其他操作之间不会产生影响或冲突。该特性主要体现在系统采用一种称为"一致性模型"的方式来保证不同时间、不同位置由不同用户同时进行的操作能够正确地协调工作(例如互斥锁机制)。

(4)持久性(durability):** 持久性是指当事务提交后其对数据库中数据的变化具有永久性的特点,并不受后续操作或数据库故障的影响。

持久性的实现主要依赖于事务日志的作用域机制,在特定的时间点上对事务的状态进行同步控制。这些记录通常分为两类:重做记录和回滚记录,在发生数据变更时需要先将数据变更的信息录入相应的重做或回滚字段中,并将对应的元数据同步至锁管理机构中以保证一致性的一致性机制得以实现。在发生故障的情况下即使整个数据库系统出现故障并需重启,在重启之后系统能够恢复之前未被写入主库中的部分数据变更并将其应用至主库中完成处理

4.事务的状态:

(1) 活动状态: 当数据库操作正在进行中时, 我们认为该事务处于活动状态;

(2)部分提交的(partially committed):

(3)处于失败状态:当事务处于活动状态或部分提交状态时,可能会因遇到错误而无法继续执行,或是由于人为地终止当前事务的执行,则称该事务处于失败状态.

对于已终止(aborted)的事务,在其部分执行后出现故障导致最终状态出现问题时,则需要将该事务中所有修改的数据重置回其初始状态。一旦完成回滚操作并使数据库恢复至该事务启动时的状态,则该事务因此进入已终止状态。

当一个事务处于部分已提交状态时,在其修改过数据已被同步至磁盘后,则完成提交。

二、如何使用事务:

  1. 事务的完整过程: 启动事务; 多个DML操作依次执行; 事务完成(处于提交成功(COMMIT)状态或发生回滚(ROLLBACK)的情况)。

2.显示事务:

(1)开启事务:

复制代码
 BEGIN;

    
 START TRANSACTION;
    
 START TRANSACTION后面可以跟随几个修饰符:
    
 READ ONLY:标识当前事务是一个只读事务,也就是属于该事务的数据库操作只能读取数据而不能修改数据
    
 READ WRITE:标识当前事务是一个读写事务,也就是属于该事务的数据库操作既能读取数据又能修改数据
    
 WITH CONSISTENT SNAPSHOT:启动一致性读

(2)一系列操作: DML语句组成

(3)提交事务或中止事务:

复制代码
 提交事务:

    
 COMMIT;
    
 回滚事务:默认回滚到最近一次的COMMIT状态
    
 ROLLBACK;
    
 ROLLBACK TO [SAVEPOINT];
    
 关于SAVEPOINT的操作(在一个事务中):
    
 新建保存点:SAVEPOINT 保存点名称;
    
 删除某个保存点:RELEASE SAVEPOINT 保存的名称

3.隐式事务:

关键字autocommit:

复制代码
 SHOW VARIABLES LIKE 'autocommit';默认为ON,此时一条DML操作是一个独立的事务

    
 SET autocommit = FALSE;关闭自动提交,对DML操作有效,对DDL操作无效
    
 在autocommit为true的情况下,使用START TRANSACTION或者BEGIN开启事务,DML操作不会自动提交数据

隐式提交的数据情况:(1)执行数据定义指令DDl;(2)在未主动提交的情况下使用或修改MySQL数据库中的表;(3)涉及事务管理的相关语句或与锁操作相关的内容;(4)用于执行数据加载操作所需的语句;(5)MySQL中用于复制数据的各种命令或操作

MySQL中completion_type参数:

completion = 0: 在默认情况下, 当COMMIT被执行时会提交事务, 而在随后的事务中则需要调用START TRANSACTION或BEGIN来开启.

completion = 1: 当提交事务后等同于执行了COMMIT AND CHAIN操作, 即启动了一个链式操作, 则在该操作中采用与当前相同的隔离级别策略.

Git默认设置为两次提交完成,在这种情况下,默认值会被设定为COMMIT=COMMIT AND RELEASE的形式,在这种特殊情况下, Git会执行一种特殊的命令模式,即每次提交都会导致与远程服务器断开连接

三、事务隔离级别:

1.数据并发问题:

(1)数据完整性破坏行为(Dirty Write): 当两个事务Session A与B操作时, 若事务A更新了未被事务B提交修改的数据, 则称此行为构成了脏写行为.

(2)脏读(Dirty Read): 对于两个事务A和B,在A读取已被事务B更新但未提交字段时, 若事务B发生回滚, 则A获取的数据为临时且无效.

(3)非重叠式读取(Non-Repeatable Read): 在同一时间段内不会同时存在多个事务试图修改同一个数据项的情况被称为非重叠式读取。
对于两个事物操作者而言,在时间轴上先有操作的是哪个?
假设在时间点t1时:

  1. 事物操作者甲对某个数据项进行了初始的read
  2. 事物操作者乙对该数据项进行了update
    随后在时间点t2时:
  3. 事物操作者甲再次对该数据项进行了new read
    此时由于data item已被修改过一次
  4. 第一次read得到的结果与第二次read结果不一致

(4)Phantom(幻读): 假设存在两个事务操作A和B,在同一数据表中执行如下操作:事务A首先从该表中获取某一字段值;随后,在同一时间段内完成对该表的更新操作,在新增了一系列数据记录之后完成任务。当事务A在完成上述操作后再次对同一数据表进行查询操作时,则会比预期多获取了几条新增的数据记录。这些新增的数据即被定义为所谓的"Phantom Records"(幻影记录)。

2.SQL中的四种隔离级别:

(1) VIEW NON-COMMITED: 查看未提交,在该隔离级别下任何事务均能访问到其他非提交事务的状态;无法避免地会引发脏 read 问题;这种隔离级别不支持重复 read 操作;同时也会导致幻 read 现象的发生。

(2)Read Committed: 读已提交的状态符合隔离原则的定义:一个事务只能看到已提交事务所执行的变化记录。这是大多数数据库系统默认采用的隔离级别,在这种情况下可以有效避免脏读问题的发生;然而,在操作过程中可能会导致不可重复读和幻读现象的产生。

(3)REPEATABLE READ:** 重复可读性:当事务A在操作一条数据时,在同一时间单位内若事务B对该数据进行更新并提交,则事务A后续再次尝试操作该数据时会发现其内容未变。此方法能够有效防止脏 reads现象,并且也能够防止不可重复 reads问题;但需注意的是幻reads问题依然存在;

(4)SERALIZABLE: 支持串行化的机制能够保证在同一张表中所有参与事务的读操作返回完全一致的数据行。在该事务执行期间禁止任何其他事务对同一张表进行插入、更新或删除操作以避免数据不一致的情况。这种方法能够有效防止所有可能发生的并发问题都能得到妥善解决;然而这种方法在性能方面存在明显不足。

隔离级别 脏读可能性 不可重复读可能性 幻读可能性 加锁读
READ UNCOMMITTED Yes Yes Yes No
READ COMMITTED No Yes Yes No
REPEATABLE READ No No Yes No
SERIALIZABLE No No No Yes

3.MySQL支持的四种隔离级别:

查看事务的隔离级别:

复制代码
    SHOW VARIABLES LIKE 'transaction_isolation';

设置事务的隔离级别:

复制代码
 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

全部评论 (0)

还没有任何评论哟~