mysql锁机制 mysql锁的分类
- 开发语言
- 2023-08-13
- 89
这篇文章给大家聊聊关于mysql锁机制,以及mysql锁的分类对应的知识点,希望对各位有所帮助,不要忘了收藏本站哦。关于MySQL中的表锁和行锁1.程序中非数据库交互操...
这篇文章给大家聊聊关于mysql锁机制,以及mysql锁的分类对应的知识点,希望对各位有所帮助,不要忘了收藏本站哦。
关于MySQL中的表锁和行锁
1.程序中非数据库交互操作导致事务挂起
将接口调用或者文件操作等这一类非数据库交互操作嵌入在SQL事务代码之中,那么整个事务很有可能因此挂起(接口不通等待超时或是上传下载大附件)。
2.事务中包含性能较差的查询SQL
事务中存在慢查询,导致同一个事务中的其他DML无法及时释放占用的行锁,引起行锁等待。
3.单个事务中包含大量SQL
通常是由于在事务代码中加入for循环导致,虽然单个SQL运行很快,但是SQL数量一大,事务就会很慢。
4.级联更新SQL执行时间较久
这类SQL容易让人产生错觉,例如:updateAset...where...in(selectB)这类级联更新,不仅会占用A表上的行锁,也会占用B表上的行锁,当SQL执行较久时,很容易引起B表上的行锁等待。
5.磁盘问题导致的事务挂起
极少出现的情形,比如存储突然离线,SQL执行会卡在内核调用磁盘的步骤上,一直等待,事务无法提交。
综上可以看出,如果事务长时间未提交,且事务中包含了DML操作,那么就有可能产生行锁等待,引起报错。
mysql串行化加的什么锁
MySQL大致可归纳为以下3种锁:
表级锁:开销小,加锁快;不会出现死锁;锁定粒度大,发生锁冲突的概率最高,并发度最低。
行级锁:开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度也最高。
页面锁:开销和加锁时间界于表锁和行锁之间;会出现死锁;锁定粒度界于表锁和行锁之间,并发度一般
mysql查询会导致锁表吗
mysql锁表或锁行的情况是:
当主键或者唯一索引的效果时,是锁行。但是如果“重复率”高时,Mysql不会把这个普通索引当做索引,即会造成一个没有索引的SQL,从而形成锁表。
特别是在UPDATE、DELETE操作时,MySQL不仅锁定WHERE条件扫描过的所有索引记录,而且会锁定相邻的键值,即所谓的next-keylocking。
怎么解决数据库Mysql自增锁问题
在innodb里里面又一个参数叫innodb_autoinc_lock_mode,它的值分别为0,1,2.
下面来说说这三个值分别是什么意思。
0:传统方式。串行自增的,并且是连续的。这样需要独占的串行锁,语句完成才释放锁,所以性能最低。例如:1、2、3、4、5、6
1:连续方式。自增的,并且是连续的。当语句申请到自增锁就释放自增锁,自增锁就可以给其它语句使用。性能会好很多。这个是系统默认的。例如:1、2、3、4、5、6
2:交错方式。多语句插入数据时,有可能自增的序列号和执行先后顺不一致,并且中间可能有断裂。一次分配一批自增值,然后下个语句就再进行分配一批自增值,阻塞很小,性能很高。例如:1、2、3、6、5
楼主说的自增锁的问题应该就是并发高的时候,语句执行完毕才会释放锁,所以可能会遇到语句阻塞。如果您不需要连续的自增id的话,可以把innodb_autoinc_lock_mode=2,并且把innodb_autoextend_increment设置大一些,例如innodb_autoextend_increment=10,这样可以缓解mysql自增锁的问题。
但是在statement-basedreplication下不一定是安全的,因为它插入的数据不一定是连续的,可能会导致一些主从不一致的情况。
mysql数据库怎么设置乐观锁
乐观锁与悲观锁不同的是,它是一种逻辑上的锁,而不需要数据库提供锁机制来支持
当数据很重要,回滚或重试一次需要很大的开销时,需要保证操作的ACID性质,此时应该采用悲观锁
而当数据对即时的一致性要求不高,重试一次不太影响整体性能时,可以采用乐观锁来保证最终一致性,同时有利于提高并发性
通常,乐观锁采用版本号/时间戳的形式实现:给数据额外增加一个版本号字段进行控制;更新时,若提交的数据所带的版本号与当前记录的版本号一致,则允许变更执行并更新版本号;若不一致,则意味着产生冲突,根据业务需求直接丢弃并返回失败,或者尝试合并
在MySQL的实践中,常见的一种使用乐观锁的方法,是在需要使用乐观锁的表中,新增一个version字段
例如:
createtableproduct_amount(
idintnotnullprimarykeyauto_increment,
product_namevarchar(64)notnull,
selling_amountintnotnull,
storing_amountintnotnull,
versionintnotnull
);
当需要更新销售中的商品数量(selling_amount)时,使用如下的SQL语句:
updateproduct_amountsetselling_amount=#{selling_amount},version=#{new_version}whereid=#{id}andversion=#{old_version};
若该语句返回1,则表示更新成功;若返回0,则表示前后的version不一致,产生冲突,更新失败
对于更新仓库中的商品数据(storing_amount)时,也是同理
不过,这样为每行记录都统一设置一个version字段的乐观锁方式,存在一个问题:上例中,如果同时需要单独对selling_amount及storing_amount进行update(两条SQL语句分别单独执行),那么后执行的一条会因为先执行的一条更新了version字段而失败,而这种失败显然是没有必要的,白白浪费了开销
一种比较好的方式是为每个需要乐观锁的字段单独设置版本号,例如对上例的改造:
createtableproduct_amount(
idintnotnullprimarykeyauto_increment,
product_namevarchar(64)notnull,
selling_amountintnotnull,
selling_versionintnotnull,
storing_amountintnotnull,
storing_versionintnotnull
);
selling_amount和storing_amount分别拥有自己的乐观锁版本号(selling_version和storing_version),更新时分别只关注自己的版本号,这样就不会因为版本号被其它字段修改而失败,提高了并发性
mysql插入锁等待超时
等待加锁线程完毕后再执行。以MyISAM表的表级写锁为例,MySql5.0说得很清楚的:当一个线程获得对一个表的写锁后,只有持有锁的线程可以对表进行更新操作。其他线程的读、写操作都会等待,直到锁被释放为止。
文章分享结束,mysql锁机制和mysql锁的分类的答案你都知道了吗?欢迎再次光临本站哦!
本文链接:http://xinin56.com/kaifa/2911.html