使用 SQL NOWAIT 的最佳方式

简介: 由于所有的主要数据库都支持此功能,Hibernate提供了一个NOWAIT选项,可以在不同数据库上调用这个功能,而且不影响代码的数据库可移植性。

由于所有的主要数据库都支持此功能,Hibernate提供了一个NOWAIT选项,可以在不同数据库上调用这个功能,而且不影响代码的数据库可移植性。



01

事务获取锁时被阻塞



关系数据库就像状态机一样运行,数据库事务将数据库从一个一致状态更改为另一个一致状态。如果出现数据一致性问题,数据库系统必须能够成功回滚所有未提交的更改,并将所有已经修改的记录还原到其之前的一致状态。即使大多数关系数据库系统使用 MVCC(多版本并发控制)机制来协调读写操作,每当执行 UPDATE 或 DELETE 操作时,仍会采用悲观锁定。每当我们对给定的表记录执行 UPDATE 或 DELETE 语句时,关系数据库系统都会获取并持有该记录的独占锁,直到当前事务以提交或回滚结束,如下图所示。


Alice的UPDATE锁定了表记录,因此当 Bob 想要使用FOR UPDATE子句获取锁时,他的锁获取请求将阻塞,直到 Alice 的交易结束或锁获取超时。使用 SELECT 查询的FOR UPDATE子句可以模拟相同的行为,如下图所示:



通过获取并保持独占锁直到事务结束,关系数据库系统避免了脏写,从而保证了事务的原子性。


02

SQL NOWAIT



为了避免SQL 语句在获取锁时被阻塞 ,我们可以使用 NOWAIT 子句,如下图所示:


现在,在获取锁时,该语句将立即抛出锁获取失败而不是阻塞,因此您可以捕获异常并继续执行其他操作,过段时间后再重新尝试获取锁。不同的数据库系统的NOWAIT 子句并不相同,见下表:


数据库 独占锁的NOWAIT子句
Oracle FOR UPDATE NOWAIT
SQL Server WITH (UPDLOCK,HOLDLOCK,ROWLOCK,NOWAIT)
PostgreSQL FOR NO KEY UPDATE NOWAIT
MySQL FOR UPDATE NOWAIT

幸运的是,在使用 JPA 和 Hibernate 时,开发人员无需编写针对特定数据库的SQL语句即可获取正确的NOWAIT 子句,因为框架会根据底层的数据库生成正确的SQL 语法。因此,开发人员只需在获取行级锁时使用LockOptions.NO_WAIT选项即可,如以下示例所示:




Post post = entityManager.find(    Post.class,    postId,    LockModeType.PESSIMISTIC_WRITE,    Map.of(        SpecHints.HINT_SPEC_LOCK_TIMEOUT,        LockOptions.NO_WAIT    ));

就是这么简单!

相关实践学习
MySQL数据库快速部署实践
本场景主要介绍如何在一台配置了CentOS 7.7版本的ECS实例(云服务器)上安装mysql,执行mysql的常用操作,学习基本的SQL语句。
相关文章
|
安全 Go 数据库
Navicat-Cracker NavicatCrackerDlg.cpp:332 -3All patch solutions are 解决Navicat 162版本注册问题的方法与分析【详细步骤】
Navicat-Cracker NavicatCrackerDlg.cpp:332 -3All patch solutions are 解决Navicat 162版本注册问题的方法与分析【详细步骤】
1194 0
|
人工智能 自然语言处理
使用Kimi+Markmap总结文件内容生成思维导图原创
一份文件内容太长,完整阅读下来太费时间,但如果使用AI进行内容提炼,再总结成思维导图,方便快速看到这份文件的核心内容和主题结构,就会极大地节约时间,目前就可以使用Kimi+Markmap这两个工具,帮我们把ppt、word、pdf等文件内容快速总结成思维导图。
2376 8
使用Kimi+Markmap总结文件内容生成思维导图原创
|
存储 安全 Java
Java 是如何做 HTTPS 双向认证的?
大家好,我是指北君。 想必大家对 HTTPS 都有一定的了解吧。今天指北君将给大家聊聊 HTTPS 是如何做安全认证的。HTTPS 是 HTTP 的一个扩展,允许计算机网络中的两个实体之间进行安全通信。HTTPS 使用TLS(传输层安全)协议来实现安全连接。
Java 是如何做 HTTPS 双向认证的?
|
存储 并行计算 编译器
面向 C++ 的现代 CMake 教程(二)(3)
面向 C++ 的现代 CMake 教程(二)
189 1
|
前端开发 应用服务中间件 网络安全
nginx配置SSL证书配置https访问网站 超详细(附加配置源码+图文配置教程)
nginx配置SSL证书配置https访问网站 超详细(附加配置源码+图文配置教程)
1506 2
|
关系型数据库 MySQL 数据库
精通MySQL:数据库管理、性能优化与最佳实践
h3> 一、引言 MySQL是一个功能强大的开源关系型数据库管理系统,广泛应用于各种Web应用、企业级应用和数据分析等领域
1466 0
使用Java读写dbf文件【附源代码】
使用Java读写dbf文件【附源代码】
|
Linux 数据安全/隐私保护 C++
如何使用Cython对python脚本加密成pyd/so
如何使用Cython对python脚本加密成pyd/so
501 0
如何使用Cython对python脚本加密成pyd/so
|
缓存 数据库 索引
什么情况下容易发生锁表及如何处理
什么情况下容易发生锁表及如何处理
819 0
|
Linux
linux 下 root 权限执行 npm install 报错:Error:EACCES:permission denied ‘xxx‘?
linux 下 root 权限执行 npm install 报错:Error:EACCES:permission denied ‘xxx‘?
485 0
linux 下 root 权限执行 npm install 报错:Error:EACCES:permission denied ‘xxx‘?