• 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的比较

  • 相关阅读:
    接入微信公众平台开发之用户关注(取消)事件触发后台自定义消息体通知给用户的实现过程
    谈缓存数据库在web开发中的重要性
    在linux服务器下日志提取的python脚本(实现输入开始时间和结束时间打包该时间段内的文件)
    关于java多线程任务执行时共享资源加锁的方式思考
    关于近期开发中遇到的同一账户多人登录造成数据库数据不一致的思考和解决(避开了数据库存状态的常用处理手段)
    spingmvc实现在程序启动时调用数据库数据
    一个前端统计图,柱形图,饼状图,折线图的前端链接
    取得ascii的例子
    BCB 延时DelayTime
    C++ Builder中串口通讯的经验之谈
  • 原文地址:https://www.cnblogs.com/kevin-yuan/p/6475697.html
Copyright © 2020-2023  润新知