zoukankan      html  css  js  c++  java
  • InnoDB锁问题 & DB事务隔离级别

    https://www.cnblogs.com/Katerina/p/11459135.html

    数据库事务隔离级别:4 种     (http://www.cnblogs.com/fjdingsd/p/5273008.html)
    read uncommitted --> read committed --> repeatable read --> Serializable
    脏读             不可重复读           幻读

    MySQL的默认隔离级别:Repeatable read。
    大多数数据库的默认级别是 Read committed,比如 Sql Server , Oracle。

    select @@tx_isolation; -- 查询当前的事务隔离级别
    set session transaction isolation level repeatable read; -- 设置当前连接的事务隔离级别(临时更改)

    注:
    如果要永久更改事务隔离级别,则要在 mysql 的 my.ini 配置中设置
    例如:transaction-isolation=Read-Committed

    数据库的脏读、不可重复读、幻读以及不可重复读和幻读的区别http://blog.csdn.net/stu_hsj/article/details/46603681

    脏读:

    脏读又称无效数据读出。一个事务读取另外一个事务还没有提交的数据叫脏读。

    例如:事务T1修改了一行数据,但是还没有提交,这时候事务T2读取了被事务T1修改后的数据,之后事务T1因为某种原因Rollback了,那么事务T2读取的数据就是脏的。

    解决办法:把数据库的事务隔离级别调整到READ_COMMITTED

    不可重复读:

    不可重复读是指在同一个事务内,两个相同的查询返回了不同的结果。 
    例如:事务T1读取某一数据,事务T2读取并修改了该数据,T1为了对读取值进行检验而再次读取该数据,便得到了不同的结果。 解决办法:把数据库的事务隔离级别调整到REPEATABLE_READ

    幻读:

    例如:系统管理员A将数据库中所有学生的成绩从具体分数改为ABCDE等级,但是系统管理员B就在这个时候插入了一条具体分数的记录,当系统管理员A改结束后发现还有一条记录没有改过来,就好像发生了幻觉一样。这就叫幻读。

    解决办法:把数据库的事务隔离级别调整到SERIALIZABLE_READ

    对 REPEATABLE-READ 的测试:(MySQL)
    参考:https://www.liaoxuefeng.com/wiki/1177760294764384/1245268672511968

    CREATE TABLE `stu` (
       `id` bigint(20) NOT NULL AUTO_INCREMENT,
       `name` varchar(255) DEFAULT NULL,
       `age` int(11) DEFAULT NULL,
       PRIMARY KEY (`id`)
     ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

    +----+---------+------+
    | id | name    | age  |
    +----+---------+------+
    | 1  | zhansan | 25   |
    | 2  | lisi    | 18   |
    +----+---------+------+

     开两个 dos 窗口来测试:

    REPEATABLE_READ 时,产生幻读测试:(MySQL)

    <参考:http://www.cnblogs.com/jack204/archive/2012/06/09/2542940.html>
    InnoDB行锁实现方式
    InnoDB行锁是通过给索引上的索引项加锁来实现的,这一点MySQL与Oracle不同,后者是通过在数据块中对相应数据行加锁来实现的。InnoDB这种行锁实现特点意味着:只有通过索引条件检索数据,InnoDB才使用行级锁,否则,InnoDB将使用表锁!

    由于MySQL的行锁是针对索引加的锁,不是针对记录加的锁,所以虽然是访问不同行的记录,但是如果是使用相同的索引键,是会出现锁冲突的。应用设计的时候要注意这一点。

    如果出现死锁,可以用SHOW INNODB STATUS命令来确定最后一个死锁产生的原因。

    共享锁(S):SELECT * FROM table_name WHERE ... LOCK IN SHARE MODE。
    排他锁(X):SELECT * FROM table_name WHERE ... FOR UPDATE。
    用SELECT ... IN SHARE MODE获得共享锁,主要用在需要数据依存关系时来确认某行记录是否存在,并确保没有人对这个记录进行UPDATE或者DELETE操作。但是如果当前事务也需要对该记录进行更新操作,则很有可能造成死锁,对于锁定行记录后需要进行更新操作的应用,应该使用SELECT... FOR UPDATE方式获得排他锁。
    给记录集显示加锁时,最好一次性请求足够级别的锁。比如要修改数据的话,最好直接申请排他锁,而不是先申请共享锁,修改时再请求排他锁,这样容易产生死锁;

    <href:http://stackoverflow.com/questions/4034976/difference-between-read-commit-and-repeatable-read>
    read commit 和 repeatable read的比较

  • 相关阅读:
    PTA L2-023 图着色问题-前向星建图 团体程序设计天梯赛-练习集
    PTA L2-004 这是二叉搜索树吗?-判断是否是对一棵二叉搜索树或其镜像进行前序遍历的结果 团体程序设计天梯赛-练习集
    PTA L2-006 树的遍历-二叉树的后序遍历+中序遍历,输出层序遍历 团体程序设计天梯赛-练习集
    HDU1166敌兵布阵(线段树单点更新)
    洛谷P1019——单词接龙(DFS暴力搜索)
    洛谷P1309——迷宫(傻瓜DFS)
    CodeForce-791B Bear and Friendship Condition(并查集)
    傻子都能懂的并查集题解——HDU1232畅通工程
    洛谷P1309——瑞士轮(归并排序)
    洛谷P1583——魔法照片(结构体排序)
  • 原文地址:https://www.cnblogs.com/kevin-yuan/p/6475697.html
Copyright © 2011-2022 走看看