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

介绍

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

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

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

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

  • 乐观的
  • OPTIMISTIC_FORCE_INCREMENT
  • PESSIMISTIC_FORCE_INCREMENT

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

  • PESSIMISTIC_READ
  • PESSIMISTIC_WRITE

读写器锁

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

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

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

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

数据库名称 共享锁语句 排他锁声明
甲骨文 更新 更新
的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/360662.shtml

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

相关文章

廖雪峰mysql安装教程 pdf_使用MySQL - 廖雪峰 Python 3 教程

MySQL是Web世界中使用最广泛的数据库服务器。SQLite的特点是轻量级、可嵌入,但不能承受高并发访问,适合桌面和移动应用。而MySQL是为服务器端设计的数据库,能承受高并发访问,同时占用的内存也远远大于SQLite。此外,MyS…

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

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

MSChart中转义符

#VALX 显示当前图例的X轴的对应文本(或数据) #VAL, #VALY, 显示当前图例的Y轴的对应文本(或数据) #VALY2, #VALY3, 显示当前图例的辅助Y轴的对应文本(或数据) #SER: 显示当前图例的名称 #LABEL 显示当前图例的标签文本 #INDEX 显示当前图例的索引 #PERCE…

mysql联合查询语句详解_实例讲解MySQL联合查询

1. 内联结:Select A.Name, B.Hobby from A, B where A.id B.id,这是隐式的内联结,查询的结果是:NameHobbyTimFootballJimmyBasketballJimmyTennisTomSoccer它的作用和 Select A.Name from A INNER JOIN B ON A.id B.…

ci 样式路径

路径里大凡从application 里面出来的,都不行,估计这已给ci设置成不能从外面读这个目录。即便是htaccess 添加application 也不行。。。 ci的模版是都放在 views下面,而且可以再嵌套在views下面的其他目录里面,但是这个时候&#…

具有Spring Boot和数据功能的Java头优先弹性搜索

在本文中,我将为您提供有关如何在Java项目中使用Elastic Search的简单介绍。 由于Spring Boot是开始我们项目的最简单,最快的方法,因此我选择使用它。 此外,我们将大量使用心爱的Spring Data的Repository Goods。 首先&#xff0…

python 表单中值为空的还需要传入么_牛掰!100行Python,自动动手打造一款多国语言翻译软件...

大家在平时的学习或者工作中,往往少不了要阅读外文的文献,或者将外文的文献翻译成中文。这时候就需要打开网页,然后进行搜索,非常的麻烦。既然是玩Python,小编就带领大家来打造一款多种语言翻译的软件,无需…

使用Visual Studio 2010 一步一步创建Powershell Module 和 Cmdlet

之前写了一个C# 调用PowerShell方法, 那么怎么反过来操作呢,也就是怎么样用C#写一个powershell命令呢? 现在就用C#写一个超级简单的Module和Cmdlet 1. 在VS中创建一个Library的项目 文件->新建->项目->C#->Class Library 在这里给…

休眠锁定模式– PESSIMISTIC_FORCE_INCREMENT锁定模式如何工作

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

Android防盗系统推荐

智游防盗是北京智游网安科技有限公司推出的一款手机防盗软件。智游防盗主要功能分为近身防盗和远程防盗。其中近身防盗包括“包包模式”,“静止模式”,“口袋模式”,“充电模式”四个防盗模式。开启“包包模式”后,当手机被拿出包…

实用程序类与函数式编程无关

最近,我被指控反对函数式编程,因为我将实用程序类称为反模式 。 绝对是错的! 好吧,我确实认为它们是一种糟糕的反模式,但是它们与函数式编程无关。 我相信有两个基本原因。 首先,函数式编程是声明性的&…

MySQL5.5加主键锁读问题【转】

【来自:http://dinglin.iteye.com/blog/1884696】背景 有同学讨论到MySQL 5.5下给大表加主键时会锁住读的问题,怀疑与fast index creation有关,这里简单说明下。 对照现象 为了说明这个问题的原因,有兴趣的同学可以做对比实验。 1…

freeredius3.0 mysql_EDIUS视频采集卡 STROM 3G HD/HD SDI

EDIUS STROM 3G HD/HD SDI高清非编系统视音频采集卡STORM 3G? 适用于视频专业人士,满足基于SDI编辑和无带化工作流程,同时可以在低成本的HDMI监/视器上预监。基于PCIe插口类型的STORM 3G解决方案包括EDIUS?非线性编辑软件,3G HD…

Openshift:使用Java 8在Wildfly 8.2.0上构建Spring Boot应用程序

OpenShift DIY墨盒是在OpenShift上测试不受支持的语言的好方法。 但是它不具有可伸缩性(您可以在此处为可伸缩DIY墨盒投票),这使得它很难与生产级Spring Boot应用程序一起使用。 但是,如果我们将Spring Boot应用程序部署到WildFly…

mysql索引ppt2020_mysql数据库索引

cmd 命令行1、mysql -u root -p ------进入数据库2、use mysql -------使用数据库3、show index from table_name; ------查看某张表的索引4、删除索引其中任一条drop index index_name on table_name ;alter table table_name drop index index_name ;alter tab…

response.sendRedirect使用注意事项 .

response.sendRedirect使用注意事项 . 问题:最近在调试xwiki的时候遇到java.lang.IllegalStateException异常,解决方案:在response.sendRedirect("")方法后加return;语句即可:原因是在程序中两次调用respons…

以编程方式确定Java类的JDK编译版本

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

mysql传输数据到中间表_mysql通过中间表实现数据的“部分复制” -电脑资料

一、基本思路1.在主库上,为不同的从库建立各自的中间表2.主库与从库之间只对“中间表”进行复制操作3.从库上,“中间表”通过触发器,实现与“实体表”的数据同步二、主库结构与配置主库结构:主库配置:三、从库结构与配…

NO1:在Windows端安装SecureCRT来连接Linux

正常情况下都不会直接在Linux服务端进行操作,实际使用服务器和工作电脑不会在同一个地方,也不允许在服务器操作。 我这里用SecureCRT 7.0来连接服务器。提供个下载,带注册机工具:http://pan.baidu.com/share/link?shareid1430164…

如何使用Spring Security和Basic身份验证保护Jersey REST服务

在我之前的博客文章“ 检查REST API是否有效的快速方法–从清单文件中获取GET详细信息”中 ,我展示了如何开发REST资源以轻松检查开发的REST API是否可用。 在本文中,我将介绍如何使用Spring Security和基本身份验证来保护此资源的安全性– “在HTTP事务…