数据库锁和隔离级别

事务

事务即acid
a,原子性,都成功或都失败
c,一致性,数据一致性
i,隔离性,事务互不干扰
d,持久性,一旦完成就会保存下来

事务隔离级别

脏读,不可重复读,幻读 是不同隔离级别需要解决的问题。每个事务都可以设置自己独立的隔离级别。

  • 读未提交 
    别的事务未提及的信息,也可以读到。脏读问题。
  • 读已提交
    自己能够读到未提交,但是别的事务被隔离了,只能读到已提交的内容。解决脏读,但是不可重复读问题存在。
  • 可重复读
    在同一个事务内,对数据的查询,数据是不变的。(不论其他事务是修改数据还是新增数据)解决不可重复读,但是幻读问题存在。如果想了解可重复读的机制,请查看我的帖子 mvcc机制
  • 串行化
    事务排队,只要有某事务对某一数据进行查询,其他事务就不能对该数据进行修改。

幻读定义:

幻读错误的理解:说幻读是 事务A 执行两次 select 操作得到不同的数据集,即 select 1 得到 10 条记录,select 2 得到 11 条记录。这其实并不是幻读,这是不可重复读的一种,只会在 R-U R-C 级别下出现,而在 mysql 默认的 RR 隔离级别是不会出现的。

幻读,并不是说两次读取获取的结果集不同,幻读侧重的方面是某一次的 select 操作得到的结果所表征的数据状态无法支撑后续的业务操作。更为具体一些:select 某记录是否存在,不存在,准备插入此记录,但执行 insert 时发现此记录已存在,无法插入,此时就发生了幻读。

select @@tx_ioslation;
set tx_isolation = 'read-uncommited';
select * from account;
start transaction;

锁机制

锁就是解决并发访问同一个资源的一种方案。 

  • 共享锁
    s锁,读锁,一个事务在对某些数据加上该锁后,其他事务只能在读该数据和对该数据加共享锁,而不能写该数据。
    select * from account where id = 1 lock in share mode;

     

  • 排他锁
    x锁,写锁。一个事务在对某些数据加上该锁后,其他事物就不能再加共享锁和修改该数据,但是可以用不加锁的方式查看数据。
    select * from account where id = 1 for update;加了排他锁,行锁。
    select * from accoutn where name = "66" for update;加了排他锁,因为条件不是索引,所以只能全表扫描,会锁表。
    update account set name = "55" where id = 1;加了排他锁,行锁。 

     

  • 意向共享锁
    IS锁,获取共享锁之前,先去查看是否有意向锁,有,就直接返回了,提高性能。
  • 意向排他锁
    IX锁,解释同上。
  • 自增锁
    就算事务没提交而是回滚,id还是会自增。
  • 临键锁
    update语句条件是一个范围,如果条件不是索引,就会加表锁,如果条件是索引,那么会加一个范围的锁,范围的值是根据底层相邻节点值来确定的,左开右闭。
  • 间隙锁
    临键锁没有匹配成功的情况下,就是间隙锁了,
  • 记录锁
    当用索引作为update条件时,比如ID= 2,这种精确的上锁,就是记录锁。

隔离级别和锁的关系

解决脏读、不可重复读依赖mvcc机制和锁机制。解决幻读,主要依赖于数据库对该serilizable事务的每一个操作都加了x锁。
串行化的时候,每一次读和写都应该是加了排他锁,才会有这种对同一条数据的读和写不能同时存在的机制出现。其他的隔离级别就是正常的写的时候加排他锁而已。如果想在可重复读的级别下也防止幻读,那么就要对每一次读和插入操作加一个排他锁。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值