mysql事务锁怎么加的 mysql事务处理( 二 )


通过强制事务排序,使其不可能相互冲突,从而解决幻读问题 。简而言之,就是在每个读的数据行上加上共享锁实现,这个级别会导致大量的超时现象和锁竞争,一般不推荐使用
为了解决数据库并发控制问题 , 如走到同一时刻客户端对同一张表做更新或者查询操作,需要对并发操作进行控制 , 因此产生了锁
共享锁的粒度是行或者元组(多个行),一个事务获取了共享锁以后 , 可以对锁定范围内的数据执行读操作
排他锁的粒度与共享锁相同,一个事务获取排他锁以后 , 可以对锁定范围内的数据执行写操作
有两个事务 A 和 B,如果事务 A 获取了一个元组的共享锁,事务 B 还可以立即获取这个元组的共享锁,但不能获取这个元组的排他锁,必须等到事务 A 释放共享锁之后 。如果事务 A 获取了一个元组的排他锁,事务 B 不能立即获取这个元组的共享锁,也不能立即获取这个元组的排他锁,必须等到 A 释放排他锁之后
意向锁是一种表锁,锁定的粒度是整张表,分为意向共享锁和意向排他锁 。意向共享锁表示一个事务有意对数据上共享锁或者排他锁 。有意表示事务想执行操作但还没真正执行
锁的粒度主要分为表锁和行锁
表锁的开销最小,同时允许的并发量也是最小 。MyISAM 存储引擎使用该锁机制 。当要写入数据时,整个表记录被锁,此时其他读/写动作一律等待 。一些特定的动作 , 如 ALTER TABLE 执行时使用的也是表锁
行锁可以支持最大的并发,InnoDB 存储引擎使用该锁机制 。如果要支持并发读/写,建议采用 InnoDB 存储引擎
mysql 的锁以及间隙锁mysql 为并发事务同时对一条记录进行读写时,提出了两种解决方案:
1)使用 mvcc 的方法,实现多事务的并发读写 , 但是这种读只是“快照读”,一般读的是历史版本数据,还有一种是“当前读”,一般加锁实现“当前读”,或者 insert、update、delete 也是当前读 。
2)使用加锁的方法 , 锁分为共享锁(读锁),排他锁(写锁)
快照读:就是select
当前读:特殊的读操作 , 插入/更新/删除操作,属于当前读 , 处理的都是当前的数据,需要加锁 。
mysql 在 RR 级别怎么处理幻读的呢?一般来说 , RR 级别通过 mvcc 机制,保证读到低于后面事务的数据 。但是 select for update 不会触发 mvcc,它是当前读 。如果后面事务插入数据并提交,那么在 RR 级别就会读到插入的数据 。所以,mysql 使用 行锁 + gap 锁(简称 next-key 锁)来防止当前读的时候插入 。
Gap Lock在InnoDB的唯一作用就是防止其他事务的插入操作,以此防止幻读的发生 。
Innodb自动使用间隙锁的条件:
MySQL从入门到精通(九) MySQL锁,各种锁 锁是计算机协调多个进程或线程并发访问某一资源的机制,在数据库中,除传统的计算资源(CPU、RAM、I/O)争用外,数据也是一种供许多用户共享的资源,如何保证数据并发访问的一致性,有效性是所有数据库必须解决的一个问题,锁冲突也是影响数据库并发访问性能的一个重要因素,从这个角度来说 , 锁对数据库而言是尤其重要,也更加复杂 。MySQL中的锁,按照锁的粒度分为:1、全局锁 , 就锁定数据库中的所有表 。2、表级锁,每次操作锁住整张表 。3、行级锁,每次操作锁住对应的行数据 。
全局锁就是对整个数据库实例加锁,加锁后整个实例就处于只读状态,后续的DML的写语句,DDL语句,已经更新操作的事务提交语句都将阻塞 。其典型的使用场景就是做全库的逻辑备份 , 对所有的表进行锁定,从而获取一致性视图,保证数据的完整性 。但是对数据库加全局锁是有弊端的,如在主库上备份,那么在备份期间都不能执行更新,业务会受影响,第二如果是在从库上备份,那么在备份期间从库不能执行主库同步过来的二进制日志 , 会导致主从延迟 。

推荐阅读