SQL的事务( 二 )

执行完成,改动的数据的还处在内存中,并没有刷写到磁盘,此时称为事务处在部分提交的状态 。

  • 失败的(failed):
    当事务处于活动的或者部分提交的状态时 , 可能遇到某些错误(数据库自身错误、操作系统错误、断电等)而无法继续执行,或人为的停止事务的执行,称为事务处于失败的状态 。
  • 中止的(aborted):
    如果事务执行了一部分而变为失败的状态,那么就需要将修改过的事务的操作还原(就是回滚操作),还原完成后,事务就出在了中止的状态 。
  • 提交的(committed):
    处于部分提交的状态的事务将修改过的数据刷写到磁盘后 , 称为事务处在提交的状态 。五、事务的隔离级别
  • 事务的隔离级别的出现 , 就是为了解决ACID中的 I(isolation 隔离性)在并发环境下,同时被操作的数据的隔离问题,同前面所述例子:
    比如事务A把余额从0改成100了,此时事务A还没有commit,而事务B进来读取余额了,此时结果是0还是100?
    以MySQL为例,MySQL是一个客户端/服务端架构的软件,对于同一个服务器来说,可以由若干个客户端与之连接,每个客户端与服务端连接上之后,称为一个会话(Session) 。每个客户端都可以在自己的会话中向服务器发出请求语句,而请求语句可以是某个事务的一部分 。对于服务器来说可以同时处理多个事务,但又要满足隔离性的特性 , 理论上在某个事务对某个数据进行访问时 , 其它事务应该进行排队 , 直到该事务提交之后 , 其它事务才能继续访问这个数据(类比Java多线程锁机制) , 但这样性能影响太大 。如果既要保持事务的隔离性,又想让服务器在处理访问同一数据的多个事务的性能尽可能高,这时候就看二者如何权衡取舍了 。
    5.1 准备数据创建一张表及数据
    CREATE TABLE student (    no INT,    name VARCHAR(20),    age INT,    PRIMARY KEY (no)) Engine=InnoDB;INSERT INTO student VALUES(1, '小明', 18);确认数据正常:
    mysql> SELECT * FROM student;+----+--------+------+| no | name   | age  |+----+--------+------+|  1 | 小明   |   18 |+----+--------+------+1 row in set (0.00 sec)5.2 数据并发问题在并发情况下,如果不保证串行执行(就是一个接一个执行),那么会出现以下几种问题:
    1. 脏写(Dirty Write)对于两个事务 Session A、Session B,如果 Session A修改了 Session B 修改过还未提交的数据,就意味着发生了脏写 。
    脏写示意图
    发生时间编号Session ASession B①BEGIN;

    BEGIN;③
    UPDATE student SET name = '李四'  WHERE no = 1;④UPDATE student SET name = '张三'  WHERE no = 1;
    ⑤COMMIT;

    ROLLBACK;已知表中仅有一条no为1、name为小明的记录 。
    Session A 与 Session B 各自开启自己的事务,Session B 的事务先将no为1的记录修改name列的值为李四,然后这条记录紧接着又 Session A 给改成了张三,并且Session A 还 COMMIT 了,按理来说此时张三就应该永久刷写到磁盘了 , 但接着Session B 将它的事务回滚了 , 对于这记录的修改全部撤回,即no为1的记录的name列的值为小明 。那对于 Session A 来说就有问题了,明明update且commit了,最后一看什么变化都没有,这是无法被容忍的问题,所以在标准SQL中的四种隔离级别中都解决了脏写的问题(就是没法复现了) 。
    2. 脏读(Dirty Read)对于两个事务 Session A、Session B,如果 Session A读取了 Session B 修改过还未提交的数据 , 之后 Session B 回滚,则 Session A 读到的数据就是临时且无效的 。
    脏读示意图
    发生时间编号Session ASession B①BEGIN;

    BEGIN;③
    UPDATE student SET name = '李四'  WHERE no = 1;④SELECR * FROM student  WHERE no = 1; (如果此时读出来是李四,而不是小明

    推荐阅读