• 数据库-事务


    什么是事务?

    多条语句作为一个整体进行操作的功能,一系列操作必须全部执行,而不能仅执行一部分;要么全部成功,要么全部失败

    例如,一个转账操作:

    – 从id=1的账户给id=2的账户转账100元
    – 第一步:将id=1的A账户余额减去100
    UPDATE accounts SET balance = balance - 100 WHERE id = 1;
    – 第二步:将id=2的B账户余额加上100
    UPDATE accounts SET balance = balance + 100 WHERE id = 2;
    这两条SQL语句必须全部执行,或者,由于某些原因,如果第一条语句成功,第二条语句失败,就必须全部撤销。

    事务的特性

    数据库事务具有ACID这4个特性:

    1. A:Atomic,原子性,将所有SQL作为原子工作单元执行,要么全部执行,要么全部不执行;
    2. C:Consistent,一致性,事务完成后,所有数据的状态都是一致的,即A账户只要减去了100,B账户则必定加上了100;
    3. I:Isolation,隔离性,数据库允许多个并发事务同时对数据库进行读写和修改,隔离型可以防止多个事务并发过程时由于交叉执行而导致的数据不一致;
    4. D:Duration,持久性,即事务完成后,对数据库数据的修改被持久化存储。

    持久性是通过 redo log (重做日志)来保证的;
    原子性是通过 undo log(回滚日志) 来保证的;
    隔离性是通过 MVCC(多版本并发控制) 或锁机制来保证的;
    一致性则是通过持久性+原子性+隔离性来保证;

    事务如何保证这些特性的?

    待学习补充?

    事务的使用

    手动把多条sql语句作为一个事务执行;
    BEGIN开启一个事务,使用COMMIT提交事务,commit将事务内的所有sql所做的修改永久保存,如果commit语句执行失败了,整个事务也会失败,例如:

    BEGIN;
    UPDATE accounts SET balance = balance - 100 WHERE id = 1;
    UPDATE accounts SET balance = balance + 100 WHERE id = 2;
    COMMIT;
    
    • 1
    • 2
    • 3
    • 4

    主动让事务失败,可以使用ROLLBACK回滚事务,整个事务就会失败,例如:

    BEGIN;
    UPDATE accounts SET balance = balance - 100 WHERE id = 1;
    UPDATE accounts SET balance = balance + 100 WHERE id = 2;
    ROLLBACK;
    
    • 1
    • 2
    • 3
    • 4

    事务的隔离级别

    问题1:为什么事务需要隔离?
    当数据库上有多个事务同时执行的时候,就可能出现脏读(dirty read)、不可重复读(non-repeatable read)、幻读(phantom read)的问题,为了解决这些问题,就有了“隔离级别”的概念

    问题2:什么是脏读、不可重复读、幻读?

    1. 脏读:一个事务读取了另一个事务改写但还未提交的数据;(还未commit,事务还可能会出现回滚,其他事务读到了脏数据)
    2. 不可重复读:同一个事务中,多次读取的数据返回结果有所不同
    3. 幻读:一个事务读取了另一个事务插入的新纪录(会出现查询数据的行数多了或者少了,从而出现不一致)
      在这里插入图片描述

    问题3:不可重复读和幻读有什么区别?

    • 不可重复读是读取了其他事务更改的数据,针对的是update操作;使用行级锁,锁定该行,事务A多次读取操作完成后才释放该锁,这个时候才允许其他事务更改刚才的数据。
    • 幻读是读取了其他事务新增的数据,针对insert和delete操作;使用表级锁,锁定整张表,事务A多次读取数据总量之后才释放该锁,这个时候才允许其他事务新增数据。

    了解完事务可能出现的问题,再看事务的隔离级别

    数据库事务的隔离级别有4个,由低到高依次为读未提交(Read uncommitted) 、读已提交(Read committed) 、可重复读(Repeatable read) 、串行化(Serializable) ,这四个级别可以逐个解决脏读 、不可重复读 、幻读 这几类问题

    隔离的越严实,效率就会越低;

    • 读未提交是指,一个事务还没提交时,它做的变更就能被别的事务看到。
    • 读提交是指,一个事务提交之后,它做的变更才会被其他事务看到。
    • 可重复读是指,一个事务执行过程中看到的数据,总是跟这个事务在启动时看到的数据是一致的。当然在可重复读隔离级别下,未提交变更对其他事务也是不可见的。
    • 串行化,顾名思义是对于同一行记录,“写”会加“写锁”,“读”会加“读锁”。当出现读写锁冲突的时候,后访问的事务必须等前一个事务执行完成,才能继续执行

    几种隔离机制可能出现的问题:
    在这里插入图片描述
    Q5: 可重复读为什么会出现幻读的现象?

    Q5 :MySQL的InnoDB引擎默认隔离级别是可重复读;但是它很大程度上避免幻读现象;

    • 针对快照读(普通 select 语句),是通过 MVCC 方式解决了幻读,因为可重复读隔离级别下,事务执行过程中看到的数据,一直跟这个事务启动时看到的数据是一致的,即使中途有其他事务插入了一条数据,是查询不出来这条数据的,所以就很好了避免幻读问题。
    • 针对当前读(select … for update 等语句),是通过 next-key lock(记录锁+间隙锁)方式解决了幻读,因为当执行 select … for update 语句的时候,会加上 next-key lock,如果有其他事务在 next-key lock 锁范围内插入了一条记录,那么这个插入语句就会被阻塞,无法成功插入,所以就很好了避免幻读问题。

    Q4:每种隔离机制的使用场景有哪些?

    可重复读:

    并发事务会引发什么问题?

    事务隔离的实现

    什么是长事务

    事务的启动方式

  • 相关阅读:
    leetcode 792. Number of Matching Subsequences(匹配的子串数量)
    caspase-2 酶抑制剂有望治疗非酒精性脂肪肝
    [附源码]计算机毕业设计JAVAjsp在线视频网站
    第三章《数组与循环》第2节:多维数组
    车载通信架构 —— 传统车内通信网络发展回顾
    华为云云耀云服务器L实例评测 | 实例评测使用之硬件参数评测:华为云云耀云服务器下的 Linux 网络监控神器 bmon
    Python 网络请求模块 urllib 、requests详解
    宝塔面板是干什么的?有哪些典型的功能作用?
    《C++ Primer》第3章 字符串、向量和数组(一)
    打开google search,从taskbar拖拽全屏应用比如Google进入分屏,页面出现Launcher报错
  • 原文地址:https://blog.csdn.net/sinat_36270007/article/details/133887505