zoukankan      html  css  js  c++  java
  • 事务及隔离级别


    事务Transaction
    SQL语句是我们给数据库发送了指令,让数据库帮我们做事情
    1.事务可以理解为是让数据库做的事情
    2.有些时候事情之内不止一条sql,存在多个组成单元
    比如: 银行系统 转账 张三 100 --->李四
    update atm set abalance = 原来-100 where aname = 张三;
    update atm set abalance = 原来+100 where aname = 李四;
    登录 查询余额 存款 取款 转账 开户 销户
    .txt文件 I/O
    缓存Map commit(); MVC分层思想 IO 缓存
    3.一件事情中的所有操作应该是统一的
    要么都成功,要么都失败
    4.事务的本质
    可以理解为
    多线程并发操作同一张表格可能带来的安全问题
    ----------------------------------------------------------------------
    事务的四大特性(ACID)
    A:Atomicity---->原子性
    一个事务中的所有操作是一个整体,不可再分
    事务中的所有操作要么都成功,要么都失败
    C:Consistency--->一致性
    一个用户操作了数据,提交以后
    另一个用户看到的数据与之前用户看到的效果是一致
    *I:Isolation---->隔离性----->(事务隔离级别)
    指的是多个用户并发访问数据库时
    一个用户操作数据库,另一个用户不能有所干扰
    多个用户之间的数据事务操作要互相隔离
    D:Durability--->持久性
    指的是一个用户操作数据的事务一旦被提交(缓存-->文件)
    他对数据库底层真实的改变是永久性的 不可返回

    ----------------------------------------------------------------------
    mysql数据库事务管理默认的效果可以更改
    autocommit变量 = on;
    show variables like '%commit%';
    show variables like 'autocommit';
    set autocommit = off; 设置自动提交关闭

    1.开启一个事务
    每一次执行的一条sql语句之前
    mysql数据库都会默认的开启
    begin; start transaction;
    2.执行操作
    insert update delete
    select
    可能不止一条语句
    3.事务的处理
    提交/回滚/保存还原点

    commit   /  rollback   /   savepoint 还原点名 / rollback to 还原点名 ; 后边三个操作都在一个事务的过程中 事务一旦commit,则永久性改变,无法回滚等
    mysql数据库会默认的执行提交事务

    -----------------------------------------------------
    事务的隔离性可能会产生多线程并发操作同一个数据库表格的问题
    会带来数据的安全隐患
    1.脏读
    一个人读到了另外一个人还没有提交的数据
    A B在操作同一张表格
    A修改了数据,还没有提交,B读取到了
    A不提交了,回滚回来,B刚刚读取到的那些数据就是无用的----脏数据
    2.不可重复读
    A B在操作同一个表格
    A先读取了一些数据,读完之后B此时将数据做了修改/删除(commit了)
    A再按照之前的条件重新读一遍,与第一次读取的不一致
    3.幻读(虚读)
    A B在操作同一个表格 A事务的正确业务逻辑应该是先查询是否存在这条记录,如果不存在,则插入

    事务A-select * from emp where id=2 记录不存在,按理可以插入对吧,然后->事务B插入insert into emp values  where id=2 (这里如果不commit,则下一步操作会超时,如果commit则报错) ->事务A插入insert into emp values  where id=2(失败-有可能报主键或其它错误)->事务A查询select * from emp where id=2发现明明查询没有记录才插入的,但插入却始终不成功,仿佛幻觉了。

    说明事务B影响到事务A的正常插入业务,导致事务A产生了不符合逻辑的情况,即明明是空记录,但是就是没法插入。

    需要考虑事务的隔离级别
    Serializable 最高 可以避免所有出现的问题 性能很慢
    Repeatable Read 可重复读 (避免脏读,不可重复读)(有幻读的风险并非一定,20%的事务存在幻读的可能,80%的事务没有幻读的风险)
    Read Committed 读已提交 (避免脏读)
    Read UnCommitted 读取未提交 (所有效果均无法保证)

    MySQL数据库提供默认隔离级别 Repeatable Read
    Oracle数据库提供默认隔离级别 Read Committed

    修改数据库中的隔离级别

    一.5.7.20之后8.0版本前使用了transaction_isolation作为别名替代tx_isolation

    命令格式:set [SESSION|GLOBAL] tx_isolation [Serializable] //session作用于当前会话,global作用于全局

    set session tx_isolation ='read-uncommitted';

    set global tx_isolation ='read-uncommitted';
    如果不放心可以查看,清楚记得变量名,可以这样查隔离级别
    select @@tx_isolation;或select @@transaction_isolation;

    也可以模糊查询,show variables like '%isolation%';

    二.8.0版本后,tx_isolation已经删除

    命令格式:SET [SESSION|GLOBAL] transaction_isolation=[0|1|2|3];

    实例:set session transaction_isolation=0;//这里可以是数字也可以是字符串

    set session transaction_isolation='read-uncommitted';

    0 --> 读未提交 (READ-UNCOMMITTED)

    1 --> 读已提交 (READ-COMMITTED)

    2 --> 可重复读 (REPEATABLE-READ)

    3 --> 序列化  (SERIALIZABLE)

    命令格式2(虽然不知道多一种写法的意义,但管它的呢):

    set [session][global] transaction isolation level [Serializable] //session作用于当前会话,global作用于全局
    实例:set gloabl transaction isolation level Serializable;

    发现一个问题:set global transaction isolation level Serializable 或者set  transaction isolation level Serializable//执行成功但查询发现没生效

    猜测带gloabl或默认 都是全局设置,全局设置都不生效?

    实际是生效了但在当前会话看不到,重连再查看发现生效了的。

     注意:这些设置重启服务后都会恢复到默认状态

    @阿拓老师在上 请受学生一拜

  • 相关阅读:
    在WAMPSERVER下增加多版本的PHP(PHP5.3,PHP5.4,PHP5.5)完美支持。
    mysql慢查询配置
    mysqlslap 一个MySQL数据库压力测试工具
    MYSQL用户操作管理大杂烩
    AIX mount nfs 文件系统失败
    rsync续传大目录一例
    TCP三次握手
    inode 耗尽
    Linux记录屏幕输出log
    《漏测问题表元素》
  • 原文地址:https://www.cnblogs.com/hebiao/p/14211736.html
Copyright © 2011-2022 走看看