事务隔离级别

概述

一个或一组sql语句组成一个执行单元,这个执行单元要么全部执行,要么全部不执行
(如果单元中某个sql执行失败,整个单元将会回滚)
转账:

1
2
update table set余额=500 where name=’张三丰’
update table set余额=1500 where name=’郭襄’

如果单独执行,数据库出现意外挂掉只执行了一个就会很尴尬

mysql的存储引擎

在mysql中的数据用各种不同的技术存储在文件(内存)中。
通过show engines查看所有mysql支持的引擎
主流 innoDB、MEMORY、MylSAM
只有innoDB支持事务

事务的ACID(acid)属性

  • 1.原子性(atomicity)
    不可在分割的工作单位

  • 2.一致性(Consistency)
    就是这边变了那边也变了,一致的变化

  • 3.隔离性(isolation)
    事务的隔离性是指事务的执行不受其他事务干扰。
    并发互不干扰(但很多时候是达不到隔离性的,要用隔离级别控制)

  • 4.持久性(Durability)
    一个事务一旦被提交,它对数据库中数据的改变就是永久性的,
    接下来的其他操作和数据库故障不应该对其有影响。不能撤销

事务的创建

  • 隐式事务:事务没有明显的开启和结束的标记
    比如insert、update、delete

  • 显示事务:事务具有明显的开启结束标记
    前提必须设置自动提交功能禁用

    1
    set autocommit = 0;(只针对当前事务有效)
  • 步骤:

    1
    2
    3
    4
    5
    6
    1.set autocommit=0;
    2.start transaction;可选的 不选也开启了
    3.编写事务中的sql(select insert update delete)
    如:
    1.update table set余额=500 where name=’张三丰’
    2.update table set余额=1500 where name=’郭襄’
  • 结束事务

    • 1.commit提交事务
    • 2.rollback回滚事务
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      set autocommit = 0;
      start transaction;
      update table set余额=500 where name=’张三丰’;
      update table set余额=1500 where name=’郭襄’;
      commit; 提交到磁盘文件
      rollback; 撤销
      savepoint 节点名,设置保存点
      (回滚点)

      delete可以回滚
      set autocommit = 0;
      start transaction;
      delete from account where id=25;
      savepoint a;
      delete from account where id=28;
      rollback to a;回滚到保存点
      truncate无法回滚

事务的隔离机制与并发性处理

有时候同时运行多个事务,当这些事务访问数据库中相同数据时,
如果没有采取有效隔离机制,就会产生下面这些问题

  • 1.脏读:T1读取了T2更新还没提交的数据,若T2回滚,T1读取的内容就是临时无效的。
  • 2.不可重复读:对于两个事务T1,T2 T1读取了一个字段,然后T2更新了该字段之后,
    T1再次读取同一字段值就不同了。
  • 3.幻读:T1读取一行发现不存在,T2插入这行,T1插入这行发现不行。

数据事务隔离性:数据库系统必须具有隔离并发运行各个事务的能力,使他们不会相互影响,避免各种并发问题。

oracle支持两种事务隔离级别

  • 1.READ COMMITED
  • 2.SERIALIZABLE
    默认隔离级别:READ COMMITED
    1
    2
    3
    4
    5
    6
    select @@tx_isolation; 查看隔离级别
    select @@transaction_isolation; mysql8格式
    设置当前mysql连接的隔离级别:
    set session transaction isolation level read uncommitted
    设置数据库系统的全局的隔离级别:(重启)
    set global transaction isolation level read uncommitted

MYSQL支持4种事务隔离级别:

  • 1.read-uncommitted 最低级别读未提交的数据
  • 2.read-committed 读已经提交的数据 避免脏读
  • 3.REPEATABLE-READ 默认 避免不可重复读
  • 4.SERIALIZABLE 避免所有问题(幻读)锁表
    串行化这边事务未完成前,别的事务会锁住。所以性能很差,只有特殊情况才用它。
    当事务2提交了插入数据,事务1插入同样数据的时候产生。

关于幻读

此时事务级别为repeatable read id为主键

1
2
3
4
5
6
7
8
9
10
开启两个session transaction
t1.
insert into table values(1, ‘afa’)
commit
t2.
select * from bb;
此时查询并没有id=1的数据
insert into table values(1, ‘werwr’)
报错:duplicate
即为幻读
分享到