Hibernate锁定模式– PESSIMISTIC_READ和PESSIMISTIC_WRITE如何工作

介绍

Java Persistence API带有完善的并发控制机制,支持隐式和显式锁定。 隐式锁定机制很简单,它依赖于:

  • 乐观锁定:实体状态更改可以触发版本增加
  • 行级锁定:基于当前运行的事务隔离级别 ,INSERT / UPDATE / DELETE语句可能会获取排他行锁定

虽然隐式锁定适用于许多情况,但显式锁定机制可以利用更细粒度的并发控制。

在之前的文章中,我介绍了显式的乐观锁定模式:

  • 乐观的
  • OPTIMISTIC_FORCE_INCREMENT
  • PESSIMISTIC_FORCE_INCREMENT

在这篇文章中,我将解开显式的悲观锁模式:

  • PESSIMISTIC_READ
  • PESSIMISTIC_WRITE

读写器锁

数据库系统是高度并发的环境,因此许多并发理论习惯用法也适用于数据库访问。 必须将并发更改序列化以保留数据完整性,因此,即使通常通过Multiversion并发控制机制对其进行补充,大多数数据库系统也使用两阶段锁定策略。

因为互斥锁定会阻碍可伸缩性(平等地进行读写操作),所以大多数数据库系统都使用读写器锁定同步方案,因此:

  • 共享(读取)锁会阻止作者,从而允许多个读者继续
  • 排他(写入)锁同时阻止读取器和写入器,从而使所有写入操作顺序地应用

因为锁定语法不是SQL标准的一部分,所以每个RDBMS都选择了不同的语法:

数据库名称 共享锁语句 排他锁声明
Oracle 更新 更新
MySQL 锁定共享模式 更新
Microsoft SQL服务器 带(HOLDLOCK,ROWLOCK) 带(上锁,上锁)
PostgreSQL 分享 更新
DB2 只供RS阅读 用于RS更新

Java持久性抽象层隐藏了数据库特定的锁定语义,提供了仅需要两个锁定模式的通用API。 使用PESSIMISTIC_READ锁定模式类型获取共享/读取锁定,而使用PESSIMISTIC_WRITE请求排他/写入锁定。

PostgreSQL行级锁定模式

在下一个测试案例中,我们将使用PostgreSQL,因为它既支持独占锁定 ,也支持共享显式锁定 。

以下所有测试将使用相同的并发实用程序,模拟两个用户:Alice和Bob。 每个测试方案将验证特定的读/写锁定组合。

private void testPessimisticLocking(ProductLockRequestCallable primaryLockRequestCallable, ProductLockRequestCallable secondaryLockRequestCallable) {doInTransaction(session -> {try {Product product = (Product) session.get(Product.class, 1L);primaryLockRequestCallable.lock(session, product);executeAsync(() -> {doInTransaction(_session -> {Product _product = (Product) _session.get(Product.class, 1L);secondaryLockRequestCallable.lock(_session, _product);});},endLatch::countDown);sleep(WAIT_MILLIS);} catch (StaleObjectStateException e) {LOGGER.info("Optimistic locking failure: ", e);}});awaitOnLatch(endLatch);
}

情况1:PESSIMISTIC_READ不阻止PESSIMISTIC_READ锁定请求

第一个测试将检查两个并发的PESSIMISTIC_READ锁定请求如何交互:

@Test
public void testPessimisticReadDoesNotBlockPessimisticRead() throws InterruptedException {LOGGER.info("Test PESSIMISTIC_READ doesn't block PESSIMISTIC_READ");testPessimisticLocking((session, product) -> {session.buildLockRequest(new LockOptions(LockMode.PESSIMISTIC_READ)).lock(product);LOGGER.info("PESSIMISTIC_READ acquired");},(session, product) -> {session.buildLockRequest(new LockOptions(LockMode.PESSIMISTIC_READ)).lock(product);LOGGER.info("PESSIMISTIC_READ acquired");});
}

运行此测试,我们得到以下输出:

[Alice]: c.v.h.m.l.c.LockModePessimisticReadWriteIntegrationTest - Test PESSIMISTIC_READ doesn't block PESSIMISTIC_READ#Alice selects the Product entity
[Alice]: Time:1 Query:{[
SELECT lockmodepe0_.id          AS id1_0_0_,lockmodepe0_.description AS descript2_0_0_,lockmodepe0_.price       AS price3_0_0_,lockmodepe0_.version     AS version4_0_0_
FROM   product lockmodepe0_
WHERE  lockmodepe0_.id = ?  
][1]} #Alice acquires a SHARED lock on the Product entity
[Alice]: Time:1 Query:{[
SELECT id
FROM   product
WHERE  id =?
AND    version =? FOR share 
][1,0]} 
[Alice]: c.v.h.m.l.c.LockModePessimisticReadWriteIntegrationTest - PESSIMISTIC_READ acquired#Alice waits for 500ms
[Alice]: c.v.h.m.l.c.LockModePessimisticReadWriteIntegrationTest - Wait 500 ms!#Bob selects the Product entity
[Bob]: Time:1 Query:{[SELECT lockmodepe0_.id          AS id1_0_0_,lockmodepe0_.description AS descript2_0_0_,lockmodepe0_.price       AS price3_0_0_,lockmodepe0_.version     AS version4_0_0_
FROM   product lockmodepe0_
WHERE  lockmodepe0_.id = ?  
][1]}#Bob acquires a SHARED lock on the Product entity
[Bob]: Time:1 Query:{[
SELECT id
FROM   product
WHERE  id =?
AND    version =? FOR share 
][1,0]} 
[Bob]: c.v.h.m.l.c.LockModePessimisticReadWriteIntegrationTest - PESSIMISTIC_READ acquired#Bob's transactions is committed
[Bob]: o.h.e.t.i.j.JdbcTransaction - committed JDBC Connection#Alice's transactions is committed
[Alice]: o.h.e.t.i.j.JdbcTransaction - committed JDBC Connection

在这种情况下,没有任何争用。 爱丽丝和鲍勃都可以获取共享锁,而不会发生任何冲突。

情况2:PESSIMISTIC_READ阻止UPDATE隐式锁定请求

第二种情况将演示共享锁如何防止并发修改。 爱丽丝将获取共享锁,而鲍勃将尝试修改锁定的实体:

@Test
public void testPessimisticReadBlocksUpdate() throws InterruptedException {LOGGER.info("Test PESSIMISTIC_READ blocks UPDATE");testPessimisticLocking((session, product) -> {session.buildLockRequest(new LockOptions(LockMode.PESSIMISTIC_READ)).lock(product);LOGGER.info("PESSIMISTIC_READ acquired");},(session, product) -> {product.setDescription("USB Flash Memory Stick");session.flush();LOGGER.info("Implicit lock acquired");});
}

测试生成以下输出:

[Alice]: c.v.h.m.l.c.LockModePessimisticReadWriteIntegrationTest - Test PESSIMISTIC_READ blocks UPDATE#Alice selects the Product entity
[Alice]: Time:0 Query:{[
SELECT lockmodepe0_.id          AS id1_0_0_,lockmodepe0_.description AS descript2_0_0_,lockmodepe0_.price       AS price3_0_0_,lockmodepe0_.version     AS version4_0_0_
FROM   product lockmodepe0_
WHERE  lockmodepe0_.id = ?  
][1]} #Alice acquires a SHARED lock on the Product entity
[Alice]: Time:0 Query:{[
SELECT id
FROM   product
WHERE  id =?
AND    version =? FOR share 
][1,0]} 
[Alice]: c.v.h.m.l.c.LockModePessimisticReadWriteIntegrationTest - PESSIMISTIC_READ acquired#Alice waits for 500ms
[Alice]: c.v.h.m.l.c.LockModePessimisticReadWriteIntegrationTest - Wait 500 ms!#Bob selects the Product entity
[Bob]: Time:1 Query:{[
SELECT lockmodepe0_.id          AS id1_0_0_,lockmodepe0_.description AS descript2_0_0_,lockmodepe0_.price       AS price3_0_0_,lockmodepe0_.version     AS version4_0_0_
FROM   product lockmodepe0_
WHERE  lockmodepe0_.id = ?  
][1]} #Alice's transactions is committed
[Alice]: o.h.e.t.i.j.JdbcTransaction - committed JDBC Connection#Bob can acquire the Product entity lock, only after Alice's transaction is committed
[Bob]: Time:427 Query:{[
UPDATE product
SET    description = ?,price = ?,version = ?
WHERE  id = ?AND version = ?
][USB Flash Memory Stick,12.99,1,1,0]} 
[Bob]: c.v.h.m.l.c.LockModePessimisticReadWriteIntegrationTest - Implicit lock acquired#Bob's transactions is committed
[Bob]: o.h.e.t.i.j.JdbcTransaction - committed JDBC Connection

尽管Bob可以选择Product实体,但UPDATE会一直延迟到提交Alice事务为止(这就是UPDATE花费427ms运行的原因)。

情况3:PESSIMISTIC_READ阻止PESSIMISTIC_WRITE锁定请求

辅助PESSIMISTIC_WRITE锁定请求也表现出相同的行为:

@Test
public void testPessimisticReadBlocksPessimisticWrite() throws InterruptedException {LOGGER.info("Test PESSIMISTIC_READ blocks PESSIMISTIC_WRITE");testPessimisticLocking((session, product) -> {session.buildLockRequest(new LockOptions(LockMode.PESSIMISTIC_READ)).lock(product);LOGGER.info("PESSIMISTIC_READ acquired");},(session, product) -> {session.buildLockRequest(new LockOptions(LockMode.PESSIMISTIC_WRITE)).lock(product);LOGGER.info("PESSIMISTIC_WRITE acquired");});
}

提供以下输出:

[Alice]: c.v.h.m.l.c.LockModePessimisticReadWriteIntegrationTest - Test PESSIMISTIC_READ blocks PESSIMISTIC_WRITE#Alice selects the Product entity
[Alice]: Time:0 Query:{[
SELECT lockmodepe0_.id          AS id1_0_0_,lockmodepe0_.description AS descript2_0_0_,lockmodepe0_.price       AS price3_0_0_,lockmodepe0_.version     AS version4_0_0_
FROM   product lockmodepe0_
WHERE  lockmodepe0_.id = ?  
][1]}#Alice acquires a SHARED lock on the Product entity
[Alice]: Time:1 Query:{[
SELECT id
FROM   product
WHERE  id =?
AND    version =? FOR share 
][1,0]} 
[Alice]: c.v.h.m.l.c.LockModePessimisticReadWriteIntegrationTest - PESSIMISTIC_READ acquired#Alice waits for 500ms
[Alice]: c.v.h.m.l.c.LockModePessimisticReadWriteIntegrationTest - Wait 500 ms!#Bob selects the Product entity
[Bob]: Time:1 Query:{[
SELECT lockmodepe0_.id          AS id1_0_0_,lockmodepe0_.description AS descript2_0_0_,lockmodepe0_.price       AS price3_0_0_,lockmodepe0_.version     AS version4_0_0_
FROM   product lockmodepe0_
WHERE  lockmodepe0_.id = ?  
][1]} #Alice's transactions is committed
[Alice]: o.h.e.t.i.j.JdbcTransaction - committed JDBC Connection#Bob can acquire the Product entity lock, only after Alice's transaction is committed
[Bob]: Time:428 Query:{[
SELECT id
FROM   product
WHERE  id = ?AND version = ?
FOR UPDATE  
][1,0]} 
[Bob]: c.v.h.m.l.c.LockModePessimisticReadWriteIntegrationTest - PESSIMISTIC_WRITE acquired#Bob's transactions is committed
[Bob]: o.h.e.t.i.j.JdbcTransaction - committed JDBC Connection

Bob的排他锁请求等待Alice的共享锁被释放。

情况4:PESSIMISTIC_READ阻止PESSIMISTIC_WRITE锁定请求,NO WAIT快速失败

Hibernate提供了一个PESSIMISTIC_NO_WAIT超时指令,该指令转换为特定于数据库的NO_WAIT锁获取策略。

PostgreSQL NO WAIT指令描述如下:

为防止该操作等待其他事务提交,请使用NOWAIT选项。 使用NOWAIT,如果无法立即锁定选定的行,该语句将报告错误,而不是等待。 注意,NOWAIT仅适用于行级锁-所需的ROW SHARE表级锁仍以常规方式获取(请参见第13章)。 如果需要无需等待就获取表级锁,则可以先将LOCK与NOWAIT选项一起使用。

@Test
public void testPessimisticReadWithPessimisticWriteNoWait() throws InterruptedException {LOGGER.info("Test PESSIMISTIC_READ blocks PESSIMISTIC_WRITE, NO WAIT fails fast");testPessimisticLocking((session, product) -> {session.buildLockRequest(new LockOptions(LockMode.PESSIMISTIC_READ)).lock(product);LOGGER.info("PESSIMISTIC_READ acquired");},(session, product) -> {session.buildLockRequest(new LockOptions(LockMode.PESSIMISTIC_WRITE)).setTimeOut(Session.LockRequest.PESSIMISTIC_NO_WAIT).lock(product);LOGGER.info("PESSIMISTIC_WRITE acquired");});
}

该测试生成以下输出:

[Alice]: c.v.h.m.l.c.LockModePessimisticReadWriteIntegrationTest - Test PESSIMISTIC_READ blocks PESSIMISTIC_WRITE, NO WAIT fails fast#Alice selects the Product entity
[Alice]: Time:1 Query:{[
SELECT lockmodepe0_.id          AS id1_0_0_,lockmodepe0_.description AS descript2_0_0_,lockmodepe0_.price       AS price3_0_0_,lockmodepe0_.version     AS version4_0_0_
FROM   product lockmodepe0_
WHERE  lockmodepe0_.id = ?  
][1]}#Alice acquires a SHARED lock on the Product entity
[Alice]: Time:1 Query:{[
SELECT id
FROM   product
WHERE  id =?
AND    version =? FOR share 
][1,0]} 
[Alice]: c.v.h.m.l.c.LockModePessimisticReadWriteIntegrationTest - PESSIMISTIC_READ acquired#Alice waits for 500ms
[Alice]: c.v.h.m.l.c.LockModePessimisticReadWriteIntegrationTest - Wait 500 ms!#Bob selects the Product entity
[Bob]: Time:1 Query:{[
SELECT lockmodepe0_.id          AS id1_0_0_,lockmodepe0_.description AS descript2_0_0_,lockmodepe0_.price       AS price3_0_0_,lockmodepe0_.version     AS version4_0_0_
FROM   product lockmodepe0_
WHERE  lockmodepe0_.id = ?  
][1]}#Bob tries to acquire an EXCLUSIVE lock on the Product entity and fails because of the NO WAIT policy
[Bob]: Time:0 Query:{[
SELECT id
FROM   product
WHERE  id = ?AND version = ?
FOR UPDATE nowait
][1,0]} 
[Bob]: o.h.e.j.s.SqlExceptionHelper - SQL Error: 0, SQLState: 55P03
[Bob]: o.h.e.j.s.SqlExceptionHelper - ERROR: could not obtain lock on row in relation "product"#Bob's transactions is rolled back
[Bob]: o.h.e.t.i.j.JdbcTransaction - rolled JDBC Connection#Alice's transactions is committed
[Alice]: o.h.e.t.i.j.JdbcTransaction - committed JDBC Connection

由于Alice已经在与产品实体相关联的数据库行上持有共享锁,因此Bob的排他锁请求立即失败。

情况5:PESSIMISTIC_WRITE阻止PESSIMISTIC_READ锁定请求

下一个测试证明排他锁将始终阻止共享锁获取尝试:

@Test
public void testPessimisticWriteBlocksPessimisticRead() throws InterruptedException {LOGGER.info("Test PESSIMISTIC_WRITE blocks PESSIMISTIC_READ");testPessimisticLocking((session, product) -> {session.buildLockRequest(new LockOptions(LockMode.PESSIMISTIC_WRITE)).lock(product);LOGGER.info("PESSIMISTIC_WRITE acquired");},(session, product) -> {session.buildLockRequest(new LockOptions(LockMode.PESSIMISTIC_READ)).lock(product);LOGGER.info("PESSIMISTIC_WRITE acquired");});
}

生成以下输出:

[Alice]: c.v.h.m.l.c.LockModePessimisticReadWriteIntegrationTest - Test PESSIMISTIC_WRITE blocks PESSIMISTIC_READ#Alice selects the Product entity
[Alice]: Time:1 Query:{[
SELECT lockmodepe0_.id          AS id1_0_0_,lockmodepe0_.description AS descript2_0_0_,lockmodepe0_.price       AS price3_0_0_,lockmodepe0_.version     AS version4_0_0_
FROM   product lockmodepe0_
WHERE  lockmodepe0_.id = ?  
][1]} #Alice acquires an EXCLUSIVE lock on the Product entity
[Alice]: Time:0 Query:{[
SELECT id
FROM   product
WHERE  id = ?AND version = ?
FOR UPDATE  
][1,0]} 
[Alice]: c.v.h.m.l.c.LockModePessimisticReadWriteIntegrationTest - PESSIMISTIC_WRITE acquired#Alice waits for 500ms
[Alice]: c.v.h.m.l.c.LockModePessimisticReadWriteIntegrationTest - Wait 500 ms!#Bob selects the Product entity
[Bob]: Time:1 Query:{[
SELECT lockmodepe0_.id          AS id1_0_0_,lockmodepe0_.description AS descript2_0_0_,lockmodepe0_.price       AS price3_0_0_,lockmodepe0_.version     AS version4_0_0_
FROM   product lockmodepe0_
WHERE  lockmodepe0_.id = ? 
][1]}#Alice's transactions is committed
[Alice]: o.h.e.t.i.j.JdbcTransaction - committed JDBC Connection#Bob can acquire the Product entity SHARED lock, only after Alice's transaction is committed
[Bob]: Time:428 Query:{[
SELECT id
FROM   product
WHERE  id =?
AND    version =? FOR share 
][1,0]}
[Bob]: c.v.h.m.l.c.LockModePessimisticReadWriteIntegrationTest - PESSIMISTIC_WRITE acquired#Bob's transactions is committed
[Bob]: o.h.e.t.i.j.JdbcTransaction - committed JDBC Connection

Bob的共享锁请求等待Alice的事务结束,以便释放所有获得的锁。

情况6:PESSIMISTIC_WRITE阻止PESSIMISTIC_WRITE锁定请求

排他锁也将阻止排他锁:

@Test
public void testPessimisticWriteBlocksPessimisticWrite() throws InterruptedException {LOGGER.info("Test PESSIMISTIC_WRITE blocks PESSIMISTIC_WRITE");testPessimisticLocking((session, product) -> {session.buildLockRequest(new LockOptions(LockMode.PESSIMISTIC_WRITE)).lock(product);LOGGER.info("PESSIMISTIC_WRITE acquired");},(session, product) -> {session.buildLockRequest(new LockOptions(LockMode.PESSIMISTIC_WRITE)).lock(product);LOGGER.info("PESSIMISTIC_WRITE acquired");});
}

测试生成以下输出:

[Alice]: c.v.h.m.l.c.LockModePessimisticReadWriteIntegrationTest - Test PESSIMISTIC_WRITE blocks PESSIMISTIC_WRITE#Alice selects the Product entity
[Alice]: Time:1 Query:{[
SELECT lockmodepe0_.id          AS id1_0_0_,lockmodepe0_.description AS descript2_0_0_,lockmodepe0_.price       AS price3_0_0_,lockmodepe0_.version     AS version4_0_0_
FROM   product lockmodepe0_
WHERE  lockmodepe0_.id = ?  
][1]} #Alice acquires an EXCLUSIVE lock on the Product entity
[Alice]: Time:0 Query:{[
SELECT id
FROM   product
WHERE  id = ?AND version = ?
FOR UPDATE  
][1,0]} 
[Alice]: c.v.h.m.l.c.LockModePessimisticReadWriteIntegrationTest - PESSIMISTIC_WRITE acquired#Alice waits for 500ms
[Alice]: c.v.h.m.l.c.LockModePessimisticReadWriteIntegrationTest - Wait 500 ms!#Bob selects the Product entity
[Bob]: Time:1 Query:{[
SELECT lockmodepe0_.id          AS id1_0_0_,lockmodepe0_.description AS descript2_0_0_,lockmodepe0_.price       AS price3_0_0_,lockmodepe0_.version     AS version4_0_0_
FROM   product lockmodepe0_
WHERE  lockmodepe0_.id = ? 
][1]}#Alice's transactions is committed
[Alice]: o.h.e.t.i.j.JdbcTransaction - committed JDBC Connection#Bob can acquire the Product entity SHARED lock, only after Alice's transaction is committed
[Bob]: Time:428 Query:{[
SELECT id
FROM   product
WHERE  id =?
AND    version =? FOR update 
][1,0]}
[Bob]: c.v.h.m.l.c.LockModePessimisticReadWriteIntegrationTest - PESSIMISTIC_WRITE acquired#Bob's transactions is committed
[Bob]: o.h.e.t.i.j.JdbcTransaction - committed JDBC Connection

Bob的排他锁请求必须等待Alice释放其锁。

结论

关系数据库系统使用锁来保留ACID保证 ,因此了解共享和排行级锁如何互操作非常重要。 显式悲观锁是一种非常强大的数据库并发控制机制,您甚至可以使用它来修复乐观锁竞争条件 。

  • 代码可在GitHub上获得 。

翻译自: https://www.javacodegeeks.com/2015/02/hibernate-locking-patterns-how-does-pessimistic_read-and-pessimistic_write-work.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/338277.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C语言中的指针有什么作用

C语言中的指针的作用是:通过指针不仅可以对数据本身,还可以对存储数据的变量地址进行操作。指针就是内存地址,指针变量是用来存放内存地址的变量。指针定义:指针,是C语言中的一个重要概念及其特点,也是掌握…

rsa php openssl,openssl rsa 使用简介

openssl命令的用法密钥的生成a. 生成非对称密钥对openssl genrsa -out rsa.keyb. 指定生成的密钥的位数,默认512openssl genrsa -out rsa_2048.key 2048c. 为私钥添加密码 (一般都不用)openssl genrsa -out rsa_des3.key -des3密钥的查看d. 查看私钥openssl rsa -in rsa.keye. …

docker 绑定宿主_将WildFly绑定到其他IP地址或多宿主上的所有地址

docker 绑定宿主用WildFly的话来说, 接口是一个逻辑名称,用于套接字可以绑定到的网络接口/ IP地址/主机名。 有两个接口:“公共”和“管理”。 “公共”接口绑定用于所有与应用程序相关的网络通信(例如,Web&#xff0…

C语言标识符有哪三类

C语言标识符有关键字、用户标识符、预定义标识符三类。C语言规定,标识符只能由字母、数字和下划线组成,并且第一个字符必须是字母或下划线,不能是数字。C语言中的标识符可分为关键字、用户标识符、预定义标识符三类。C语言规定,标…

php system 执行失败,PHP 执行 system、exec 等函数发生错误

2012-12-06 20:451932人阅读评论(0)往往在调用system、exec 等函数时,要么没有反应,要么出错:原因很多,以下是抄别人的:错误分析:1、Warning: system() has been disabled for security reasons该错误是由于…

Hibernate锁定模式– PESSIMISTIC_FORCE_INCREMENT锁定模式如何工作

介绍 在上 一篇 文章中 ,我介绍了OPTIMISTIC_FORCE_INCREMENT锁定模式,并将其应用于将子实体版本更改传播到锁定的父实体。 在本文中,我将介绍PESSIMISTIC_FORCE_INCREMENT锁定模式,并将其与乐观的锁定模式进行比较。 相像多于不…

C语言中字符串的结束标志是什么

C语言中字符串的结束标志是【\0】。C语言中没有专门的字符串变量,通常用一个字符数组来存放一个字符串,字符串总是以【\0】作为结束符。\0就是8位的00000000,因为字符类型中并没有对应的这个字符,所以这么写。\0就是 字符串结束标…

php 5.6.27 在某些机器上正常,在 Windows 10 64、PHP 5.6 下重命名中文名文件,提示错误的解决...

1、重命名某个目录中的文件名,其代码,如图1图12、报错:rename(E:/wwwroot/avatar/BEIJI/侯森.jpg,E:/wwwroot/avatar/BEIJI/378477.jpg): ϵͳ�Ҳ���ָ���&am…

c语言中字符常量是什么?

c语言中字符常量是什么?字符常量:一个用单引号括起来的单个字符(或字符转义序列或三字母词)实质(含义):是一个整形值。属于四大基本数据类型(分别是整型,浮点型&#xff…

Hibernate锁定模式– OPTIMISTIC_FORCE_INCREMENT锁定模式如何工作

介绍 在我以前的文章中 ,我解释了OPTIMISTIC锁定模式是如何工作的,以及它如何帮助我们同步外部实体状态更改。 在本文中,我们将介绍OPTIMISTIC_FORCE_INCREMENT锁定模式的使用模式。 使用LockModeType.OPTIMISTIC ,将在当前正在运…

java camel swagger,java – CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES没有反映在swagger.json中

我正在使用Jersey,Jax-rs和swagger(Spring for injection).我的对象有一些成员和嵌入对象,其名称由多个单词组成,在代码中我使用camelCase.我定义了一个解析器,因此按照标准惯例将它们作为下划线发出.问题是,招摇是显然没有拿起这个解析器,所以对象仍然在swagger json中显示为c…

c语言的输入输出语句有哪些?

c语言的输入输出语句有:“getchar(void);”和“putchar(int c);”、“scanf("格式控制字符串",地址列表);”和“printf("格式控制字符串",输出列表);”、“gets()”和“puts()”等等。一:控制台输入输出(1)字符数据的输入/输出字符输…

primefaces_PrimeFaces:在动态生成的对话框中打开外部页面

primefaces我已经在即将出版的PrimeFaces Cookbook版本2中写过一篇食谱的博客。 在这篇文章中,我想发表第二篇关于一个名为Dialog Framework的小型框架的文章。 我个人喜欢它,因为我记得我为使用Struts框架付出同样的代价。 当您想将外部页面加载到弹出窗…

c语言源文件经过编译后生成文件的后缀是什么?

c语言源文件经过编译后,生成文件的后缀是“.obj”。C语言源文件后缀名是“.c”,编译生成的文件后缀名是“.obj”,连接后可执行文件的后缀名是“.exe”。C语言创建程序的步骤:编辑:就是创建和修改C程序的源代码-我们编写…

php 去掉nbsp,php 正则去掉pnbsp;/p 空格 nbsp;

$strFactory Supply High Quality Maitake Mushroom Extract Powder Bulk$uuupreg_replace("/(\s|\&nbsp\;| |\xc2\xa0)/","",$str);echo str_replace(很完美php的str_replace函数怎么把php的str_replace函数怎么把$html"fdasf";echo $stri…

java编译器jdk版本_以编程方式确定Java类的JDK编译版本

java编译器jdk版本当需要确定使用哪个JDK版本来编译特定的Java .class文件时, 通常使用的方法是使用javap并在javap输出中查找列出的“主要版本”。 我在我的博客文章Autoboxing,Unboxing和NoSuchMethodError中引用了这种方法,但是在继续以编…

c语言指针用法有哪些

c语言指针用法:一,指针定义:指针变量的取值范围取值0~4G,是一种数据类型(无符号整数,代表了内存编号)。它可以用来定义变量(与int、long一样),与int、long不同的它存储整…

java转换汇编,请问如何把JAVA程序转为汇编?

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼import java.util.Scanner;public class Lab1 {public static void main(String arg[]){int a,i,j,n;boolean flagtrue;Scanner inputnew Scanner (System.in);System.out.printf("Enter an integer that is greater than 1:&…

ogm session_带有Hibernate OGM的NoSQL –第一部分:持久化您的第一个实体

ogm sessionHibernate OGM的第一个最终版本已经发布 ,团队从发布狂潮中恢复了一些。 因此,他们考虑开设一系列教程风格的博客,使您有机会轻松地从Hibernate OGM重新开始。 感谢Gunnar Morling( gunnarmorling )创建了本…

php array assoc,如何学习PHP array_intersect_assoc()

如何学习PHP array_intersect_assoc()定义和用法array_intersect_assoc() 函数返回两个或多个数组的交集数组。与 array_intersect() 函数 不同的是,本函数除了比较键值,还比较键名。返回的数组中元素的键名保持不变。语法array_intersect_assoc(array1,…