SQL 事务

2021-01-03   145 次阅读


事务

事务的概述

事务的概念

  • 事务:指的是逻辑上的一组操作,组成这组操作的各个逻辑单元,要么全部成功,要么全部失败(原子性)。
  • 事务的特性:
    • 原子性 :事务的不可分割性,一个完整事务的各个逻辑单元不能被分割
    • 一致性 :事务执行的前后,数据完整性保持一致
    • 隔离性 :事务的执行不受到其他事务的干扰
    • 持久性 :事务一旦结束,数据就持久化到数据库当中

事务的简单使用

我们有一张用户存储表(account),如下:

userIduserNamemoney
0001张憨憨10000
0002李笨笨10000
0003王蠢蠢10000

现在我们要完成一个转账操作,例如:

张憨憨给李笨笨转账3000元,则需要执行SQL语句如下:

-- 此时我们只是简单的示范,不考虑金钱越界的问题
update account set money = money - 3000 where userName = '张憨憨';
update account set money = money + 3000 where userName = '李笨笨';

那么这两个操作必须同时完成才能完成转账操作,一旦一个失败另一个必须也无法执行。我们需要用到事务操作,具体如下:

#开启事务
start transaction;

[[逻辑单元code]]...
update account set money = money - 3000 where userName = '张憨憨';
update account set money = money + 3000 where userName = '李笨笨';

#提交事务
commit;
#回滚事务,返回最后一个事务执行前的结果
rollback;

事务的隔离级别

  • 如果不考虑事务的隔离性,将会引发一些安全问题主要体现在读取数据上( 多个事务并行的时候 ):

    • 脏读 :一个事务在执行过程中读取到了另外一个事务未提交的数据,导致查询结果不一致
    • 不可重复读 :一个事务在执行过程中读取到了另一个事务已经提交的update的数据,导致多次查询结果不一致
    • 虚读 :一个事务在执行过程中读到了另一个事务已经提交的insert的数据,导致多次查询不一致
  • 解决上述的问题设置了事务的隔离级别(从上往下隔离级别依次提高,效率依次降低):

    • read uncommitted:脏读、不可重复读和虚读都有可能发生。
    • read committed:避免脏读,不可重复读和虚读有可能发生。
    • repeatable read(mysql默认级别):避免脏读和不可重复读,虚读有可能发生。
    • serializable:脏读、不可重复读和虚读都不可能发生。
  • 设置隔离级别指令:

    SET SESSION TRANSACTION ISOLATION LEVEL read [PARAM];
    
  • serializable避免虚读的方式,使用串行化操作,一个事务未进行提交,另外一个事务就不可以执行查询等操作。

Q.E.D.

知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议

If you don't come, I will snow.