MySQL复习(五)

一、事务

事务(trasaction)是完成一个完整事件的一系列SQL语句。这一组SQL语句是一条船上的蚂蚱,要不然都成功, 要不然都失败,如果一部分执行成功一部分执行失败那成功的那一部分就会复原(revert)以保持数据的一致性。

事务的四大ACID 特性

1. Atomicity 原子性,即整体性,不可拆分性(unbreakable),所有语句必须都执行成功事务才算完成,否则只要有语句执行失败,已执行的语句也会被复原

2. Consistency 一致性,指的是通过事务我们的数据库将永远保持一致性状态,比如不会出现没有完整订单项目的订单 ;在数据库系统中,如果多个事务在执行之前和之后对同一数据进行读取,它们所读取到的数据结果是相同的。这表明这些事务在读取数据时遵循了数据库的隔离性原则,即读取到的数据是一致的,不会因为其他事务的操作而改变

3. Isolation 隔离性,指事务间是相互隔离互不影响的,尤其是需要访问相同数据时。具体而言,如果多个事务要修改相同数据,该数据会被锁定,每次只能被一个事务有权修改,其它事务必须等这个事务执行结束后才能进行

4. Durability 持久性,指的是一旦事务执行完毕,这种修改就是永久的,任何停电或系统死机都不会影响这种数据修改

  •  用 START TRANSACTION 来开始创建事务,用 COMMIT 来关闭事务(这是两个单独的语句)
  • USE sql_store;
    
    START TRANSACTION;
    
    INSERT INTO orders (customer_id, order_date, status)
    
    VALUES (1, '2019-01-01', 1);
    
    -- 只需明确声明并插入这三个【非自增不可空字段】
    
    INSERT INTO order_items
    
    -- 所有字段都是必须的(是不可空的意思吗?那有默认值和自增呢?),就不必申明了
    
    VALUES (last_insert_id(), 1, 2, 3);
    
    COMMIT;

    当 MySQL 看到上面这样的事务语句组,会把所有这些更改写入数据库,如果有任何一个更改失败,会自动撤销之前的修改,这种情况被称为事务被退回(is rolled back)

为了模拟退回的情况,可以用 Ctrl + Enter 逐条执行语句,执行一半,即录入了订单还没录入订单项目时断开连接 (模拟客户端或服务器崩溃或断网之类的情况),重连后会发现订单和订单项目都没有录入

 ROLLBACK

多数时候是用上面的 START TRANSACTION; + COMMIT; 来创建事务,但当我们想先对事务里语句进行测试/错误检查并因此想在执行结束后手动退回时,可以将最后的 COMMIT; 换成 ROLLBACK;,这会退回事务并撤销所有的更改

autocommit

我们执行的每一个语句(可以是增删查改 SELECT、INSERT、UPDATE 或 DELETE 语句),就算没有 START

TRANSACTION + COMMIT,也都会被 MySQL 包装(wrap)成事务并在没有错误的前提下自动提交,这个过程由一个叫做 autocommit 的系统变量控制,默认开启。

因为有 autocommit 的存在,当事务只有一个语句时,用不用 START TRANSACTION + COMMIT 都一样,但要将多个语句作为一个事务时就必须要加 START TRANSACTION + COMMIT 来手动包装了

SHOW VARIABLES LIKE 'autocommit';

并发

之前都只有一个用户访问数据,现实中常出现多个用户访问相同数据的情况,这被称为“并发”(concurrency),当一个用户企图修改另一个用户正在检索或修改的数据时,并发会成为一个问题

四个并发问题:

1. Lost Updates 丢失更新:两个事务更新同一行,最后提交的事务将覆盖先前所做的更改

2. Dirty Reads 脏读:读取了未提交的数据

3. Non-repeating Reads 不可重复读取 (或 Inconsistent Read 不一致读取):在事务中读取了相同的数据两次,但得到了不同的结果

4. Phantom Reads 幻读:在查询中缺失了一行或多行,因为另一个事务正在修改数据而我们没有意识到事务的修改,我们就像遇见了鬼或者幽灵

四个标准的事务隔离等级:

1. Read Uncommitted 读取未提交:无法解决任何一个问题,因为事务间并没有任何隔离,他们甚至可以读取彼此未提交的更改

2. Read Committed 读取已提交:给予事务一定的隔离,这样我们只能读取已提交的数据,这防止了Dirty Reads脏读,但在这个级别下,事务仍可能读取同个内容两次而得到不同的结果,因为另一个事务可能在两次读取之间更新并提交了数据,也就是它不能防止Non-repeating Reads 不可重复读取 (或 Inconsistent Read 不一致读取)

3. Repeatable Read 可重复读取:在这一级别下,我们可以确信不同的读取会返回相同的结果,即便数据在这期间被更改和提交

4. Serializable 序列化:可以防止以上所有问题,这一级别还能防止幻读,如果数据在我们执行过程中改变了,我们的事务会等待以获取最新的数据,但这很明显会给服务器增加负担,因为管理等待的事务需要消耗额外的储存和CPU资源

总的来说,一般保持默认隔离等级,只在特别需要时才做改变

SHOW VARIABLES LIKE 'transaction_isolation';

-- transaction isolation 事务隔离等级

SET [SESSION]/[GLOBAL] TRANSACTION ISOLATION LEVEL SERIALIZABLE;

  • 7
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值