PESSIMISTIC_READ PESSIMISTIC_WRITE 与 共享锁 排它锁

2023-12-16 15:32

本文主要是介绍PESSIMISTIC_READ PESSIMISTIC_WRITE 与 共享锁 排它锁,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

http://suene.iteye.com/blog/1756295

可以使用 @Lock , 里面填入的是 JPA 的 LockModeType 


Java代码   收藏代码
  1. @Lock(LockModeType.PESSIMISTIC_READ)  
  2. public List<User> findByUsername(String username);  

对应的 sql 就是: 
Java代码   收藏代码
  1. select * from t_user where username=? lock in share mode  



Java代码   收藏代码
  1. @Lock(LockModeType.PESSIMISTIC_WRITE)  
  2. public List<User> findByUsername(String username);  

对应的 sql 就是: 
Java代码   收藏代码
  1. select * from t_user where username=? for update  


以上是jpa对于锁的实现,可见:

PESSIMISTIC_READ共享锁 
PESSIMISTIC_WRITE排他锁 
   


http://blog.csdn.net/cug_jiang126com/article/details/50544728


深入理解SELECT ... LOCK IN SHARE MODE和SELECT ... FOR UPDATE


概念和区别

SELECT ... LOCK IN SHARE MODE走的是IS锁(意向共享锁),即在符合条件的rows上都加了共享锁,这样的话, 其他session可以读取这些记录,也可以继续添加IS锁,但是无法修改这些记录直到你这个加锁的session执行完成(否则直接锁等待超时)。

SELECT ... FOR UPDATE 走的是IX锁(意向排它锁),即在符合条件的rows上都加了排它锁, 其他session也就无法在这些记录上添加任何的S锁或X锁。如果不存在一致性非锁定读的话,那么其他session是无法读取和修改这些记录的,但是innodb有非锁定读(快照读并不需要加锁),for update之后并不会阻塞其他session的快照读取操作,除了select ...lock in share mode和select ... for update这种显示加锁的查询操作。

通过对比,发现for update的加锁方式无非是比lock in share mode的方式多阻塞了select...lock in share mode的查询方式,并不会阻塞快照读。

应用场景

在我看来,SELECT ... LOCK IN SHARE MODE的应用场景适合于 两张表存在关系时的写操作 ,拿mysql官方文档的例子来说,一个表是child表,一个是parent表,假设child表的某一列child_id映射到parent表的c_child_id列,那么从业务角度讲,此时我直接insert一条child_id=100记录到child表是存在风险的, 因为刚insert的时候可能在parent表里删除了这条c_child_id=100的记录,那么业务数据就存在不一致的风险。正确的方法是再插入时执行select * from parent where c_child_id=100 lock in share mode,锁定了parent表的这条记录,然后执行insert into child(child_id) values (100)就ok了。


但是如果是同一张表的应用场景, 举个例子,电商系统中计算一种商品的剩余数量,在产生订单之前需要确认商品数量>=1,产生订单之后应该将商品数量减1。
1 select amount from product where product_name='XX';
2 update product set amount=amount-1 where product_name='XX';


显然1的做法是是有问题,因为如果1查询出amount为1,但是这时正好其他session也买了该商品并产生了订单,那么amount就变成了0,那么这时第二步再执行就有问题。
那么采用lock in share mode可行吗,也是不合理的,因为两个session同时锁定该行记录时,这时两个session再update时必然会产生死锁导致事务回滚。以下是操作范例(按时间顺序)


session1
mysql> begin;
Query OK, 0 rows affected (0.00 sec)


mysql> select * from test_jjj lock in share mode;
+-----+------------+
| id  | name       |
+-----+------------+
| 234 | asdasdy123 |
| 123 | jjj        |
+-----+------------+
2 rows in set (0.00 sec)


session2(同样锁定了相同的行)
mysql> begin;
Query OK, 0 rows affected (0.00 sec)


mysql> select * from test_jjj lock in share mode;
+-----+------------+
| id  | name       |
+-----+------------+
| 234 | asdasdy123 |
| 123 | jjj        |
+-----+------------+
2 rows in set (0.00 sec)


session1(这时session1再update时就会引起锁等待)
mysql> update test_jjj set name='jjj1' where name='jjj';     等待session2锁


session2( 这时session2同样update后,等待session1的锁,就会检测到死锁,回滚session2, 注意执行时间不要超过session1的锁等待超时检测时间,即不要超过innodb_lock_wait_timeout设置的值)
mysql> update test_jjj set name='jjj1' where name='jjj';
ERROR 1213 (40001): Deadlock found when trying to get lock; try restarting transaction


session1(此时session1执行完成)
mysql> update test_jjj set name='jjj1' where name='jjj';
Query OK, 1 row affected (29.20 sec)
Rows matched: 1  Changed: 1  Warnings: 0


通过该案例可知lock in share mode的方式在这个场景中不适用,我们需要使用for  update的方式直接加X锁,从而短暂地阻塞session2的select...for update操作 ;以下是操作范例


session1
mysql> begin;
Query OK, 0 rows affected (0.00 sec)


mysql> select * from test_jjj for update;
+-----+------------+
| id  | name       |
+-----+------------+
| 234 | asdasdy123 |
| 123 | jjj1       |
+-----+------------+
2 rows in set (0.00 sec)


session2(此时session2处于锁等待状态,得不到结果)
mysql> begin;
Query OK, 0 rows affected (0.00 sec)


mysql> select * from test_jjj for update;


session1(这时session1 update之后提交,可完成)
mysql> update test_jjj set name='jjj1' where name='jjj';
Query OK, 0 rows affected (0.00 sec)
Rows matched: 0  Changed: 0  Warnings: 0


mysql> commit;
Query OK, 0 rows affected (0.00 sec)


session2( session1提交之后session2刚才的查询结果就出来了 ,也就可以再次update往下执行了)
mysql> select * from test_jjj for update;
+-----+------------+
| id  | name       |
+-----+------------+
| 234 | asdasdy123 |
| 123 | jjj1       |
+-----+------------+
2 rows in set (37.19 sec)
mysql> select * from test_jjj for update;
+-----+------------+
| id  | name       |
+-----+------------+
| 234 | asdasdy123 |
| 123 | jjj1       |
+-----+------------+
2 rows in set (37.19 sec)


mysql> update test_jjj set name='jjj1' where name='jjj';
Query OK, 0 rows affected (0.00 sec)
Rows matched: 0  Changed: 0  Warnings: 0


mysql> commit;

Query OK, 0 rows affected (0.00 sec)

通过对比,lock in share mode适用于两张表存在业务关系时的一致性要求,for  update适用于操作同一张表时的一致性要求。


这篇关于PESSIMISTIC_READ PESSIMISTIC_WRITE 与 共享锁 排它锁的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/500959

相关文章

怎么让1台电脑共享给7人同时流畅设计

在当今的创意设计与数字内容生产领域,图形工作站以其强大的计算能力、专业的图形处理能力和稳定的系统性能,成为了众多设计师、动画师、视频编辑师等创意工作者的必备工具。 设计团队面临资源有限,比如只有一台高性能电脑时,如何高效地让七人同时流畅地进行设计工作,便成为了一个亟待解决的问题。 一、硬件升级与配置 1.高性能处理器(CPU):选择多核、高线程的处理器,例如Intel的至强系列或AMD的Ry

# VMware 共享文件

VMware tools快速安装 VMware 提供了 open-vm-tools,这是 VMware 官方推荐的开源工具包,通常不需要手动安装 VMware Tools,因为大多数 Linux 发行版(包括 Ubuntu、CentOS 等)都包含了 open-vm-tools,并且已经优化以提供与 VMware 环境的兼容性和功能支持。 建议按照以下步骤安装 open-vm-tools 而不

未来工作趋势:零工小程序在共享经济中的作用

经济在不断发展的同时,科技也在飞速发展。零工经济作为一种新兴的工作模式,正在全球范围内迅速崛起。特别是在中国,随着数字经济的蓬勃发展和共享经济模式的深入推广,零工小程序在促进就业、提升资源利用效率方面显示出了巨大的潜力和价值。 一、零工经济的定义及现状 零工经济是指通过临时性、自由职业或项目制的工作形式,利用互联网平台快速匹配供需双方的新型经济模式。这种模式打破了传统全职工作的界限,为劳动

vue 父组件调用子组件的方法报错,“TypeError: Cannot read property ‘subDialogRef‘ of undefined“

vue 父组件调用子组件的方法报错,“TypeError: Cannot read property ‘subDialogRef’ of undefined” 最近用vue做的一个界面,引入了一个子组件,在父组件中调用子组件的方法时,报错提示: [Vue warn]: Error in v-on handler: “TypeError: Cannot read property ‘methods

【C++】作用域指针、智能指针、共享指针、弱指针

十、智能指针、共享指针 从上篇文章 【C++】如何用C++创建对象,理解作用域、堆栈、内存分配-CSDN博客 中我们知道,你的对象是创建在栈上还是在堆上,最大的区别就是对象的作用域不一样。所以在C++中,一旦程序进入另外一个作用域,那其他作用域的对象就自动销毁了。这种机制有好有坏。我们可以利用这个机制,比如可以自动化我们的代码,像智能指针、作用域锁(scoped_lock)等都是利用了这种机制。

OpenStack:Glance共享与上传、Nova操作选项解释、Cinder操作技巧

目录 Glance member task Nova lock shelve rescue Cinder manage local-attach transfer backup-export 总结 原作者:int32bit,参考内容 从2013年开始折腾OpenStack也有好几年的时间了。在使用过程中,我发现有很多很有用的操作,但是却很少被提及。这里我暂不直接

基于springboot+vue+uniapp的“共享书角”图书借还管理系统小程序

开发语言:Java框架:springboot+uniappJDK版本:JDK1.8服务器:tomcat7数据库:mysql 5.7(一定要5.7版本)数据库工具:Navicat11开发软件:eclipse/myeclipse/ideaMaven包:Maven3.3.9 系统展示 后台登录界面 管理员功能界面 出借者管理 图书信息管理 图书归还管理 出租收入管理

Unstructured cannot write mode RGBA as JPEG 错误解决

Unstructured cannot write mode RGBA as JPEG 错误解决 0. 错误详细1. 解决方法 0. 错误详细 Image Extraction Error: Skipping the failed imageTraceback (most recent call last):File "/root/miniconda3/envs/learn-y

[轻笔记] pip install : Read timed out. (closed)

添加超时参数(单位秒) pip --default-timeout=10000 install ${package_name}

Cannot read property ‘length‘ of null while opening vscode terminal

同一问题地址:Cannot read property ‘length’ of null while opening vscode terminal 问题描述 One day, 我在ubuntu 18.04下用vscode打开一个项目,并想和往常一样在vscode使用终端,发现报错Cannot read property 'length' of null。 解决 打开setting.jso