pooled-jms_Hibernate隐藏的宝石:pooled-lo优化器

article/2025/10/6 20:21:01

pooled-jms

介绍

在这篇文章中,我们将揭示一个序列标识符生成器,​​它结合了标识符分配效率和与其他外部系统的互操作性(同时访问底层数据库系统)。

传统上,有两种序列标识符策略可供选择。

  • 序列标识符,对于每个新值分配总是命中数据库。 即使使用数据库序列预分配,我们也要花费大量的数据库往返费用。
  • seqhilo标识符,使用hi / lo算法。 该生成器在内存中计算一些标识符值,因此减少了数据库往返调用。 这种优化技术的问题在于当前的数据库序列值不再反映当前的最高内存生成值。 数据库序列用作存储区编号,因此其他系统很难与所讨论的数据库表进行互操作。 其他应用程序必须知道高/低标识符策略的内部工作方式,才能正确生成非冲突标识符。

增强的标识符

Hibernate提供了一类新的标识符生成器 ,解决了原始标识符生成器的许多缺点。 增强的标识符生成器没有固定的标识符分配策略。 优化策略是可配置的,我们甚至可以提供自己的优化实现。 默认情况下,Hibernate随附以下内置优化器 :

  • none :每个标识符都是从数据库中获取的,因此等效于原始序列生成器。
  • hi / lo :它使用hi / lo算法,与原始seqhilo生成器等效。
  • 合并的 :此优化器使用高/低优化策略,但是当前内存中标识符的最高边界是从实际数据库序列值中提取的。
  • pooled-lo :它类似于优化器,但是数据库序列值用作当前内存中的最低边界

在正式发布公告中 , 公告了合并的优化器可与其他外部系统进行互操作:

即使其他应用程序也在插入值,我们也将是绝对安全的,因为SEQUENCE本身将处理应用此增量大小。

这实际上是我们正在寻找的东西。 当其他外部系统在同一数据库表中同时插入行时,标识符生成器既高效又不会冲突。

测试时间

以下测试将检查新的优化器如何与其他外部数据库表插入配合使用。 在我们的例子中,外部系统将是在同一数据库表/序列上的一些本机JDBC插入语句。

doInTransaction(new TransactionCallable<Void>() {@Overridepublic Void execute(Session session) {for (int i = 0; i < 8; i++) {session.persist(newEntityInstance());}session.flush();assertEquals(8, ((Number) session.createSQLQuery("SELECT COUNT(*) FROM sequenceIdentifier").uniqueResult()).intValue());insertNewRow(session);insertNewRow(session);insertNewRow(session);assertEquals(11, ((Number) session.createSQLQuery("SELECT COUNT(*) FROM sequenceIdentifier").uniqueResult()).intValue());List<Number> ids = session.createSQLQuery("SELECT id FROM sequenceIdentifier").list();for (Number id : ids) {LOGGER.debug("Found id: {}", id);}for (int i = 0; i < 3; i++) {session.persist(newEntityInstance());}session.flush();return null;}
});

池优化器

我们将首先使用优化器策略:

@Entity(name = "sequenceIdentifier")
public static class PooledSequenceIdentifier {@Id@GenericGenerator(name = "sequenceGenerator", strategy = "enhanced-sequence",parameters = {@org.hibernate.annotations.Parameter(name = "optimizer", value = "pooled"),@org.hibernate.annotations.Parameter(name = "initial_value", value = "1"),@org.hibernate.annotations.Parameter(name = "increment_size", value = "5")})@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequenceGenerator")private Long id;
}

运行测试最终会引发以下异常:

DEBUG [main]: n.t.d.l.SLF4JQueryLoggingListener - Name: Time:0 Num:1 Query:{[insert into sequenceIdentifier (id) values (?)][9]} 
DEBUG [main]: n.t.d.l.SLF4JQueryLoggingListener - Name: Time:0 Num:1 Query:{[insert into sequenceIdentifier (id) values (?)][10]} 
DEBUG [main]: n.t.d.l.SLF4JQueryLoggingListener - Name: Time:0 Num:1 Query:{[insert into sequenceIdentifier (id) values (?)][26]} 
WARN  [main]: o.h.e.j.s.SqlExceptionHelper - SQL Error: -104, SQLState: 23505
ERROR [main]: o.h.e.j.s.SqlExceptionHelper - integrity constraint violation: unique constraint or index violation; SYS_PK_10104 table: SEQUENCEIDENTIFIER
ERROR [main]: c.v.h.m.l.i.PooledSequenceIdentifierTest - Pooled optimizer threw
org.hibernate.exception.ConstraintViolationException: could not execute statementat org.hibernate.exception.internal.SQLExceptionTypeDelegate.convert(SQLExceptionTypeDelegate.java:72) ~[hibernate-core-4.3.5.Final.jar:4.3.5.Final]	
Caused by: java.sql.SQLIntegrityConstraintViolationException: integrity constraint violation: unique constraint or index violation; SYS_PK_10104 table: SEQUENCEIDENTIFIERat org.hsqldb.jdbc.JDBCUtil.sqlException(Unknown Source) ~[hsqldb-2.3.2.jar:2.3.2]

我不确定这是错误还是仅是设计限制,但是合并的优化器不满足互操作性要求。

为了可视化发生的情况,我在下图中总结了序列调用:

池优化器

优化器检索当前序列值时,它将使用它来计算最低的内存边界。 最小值是实际的先前序列值,并且其他外部INSERT语句可能已经使用了该值。

Pool-lo优化器

幸运的是,还有另外一个要测试的优化器(参考文档中未提及)。 pool-lo优化器使用当前数据库序列值作为最低的内存边界,因此其他系统可以自由使用下一个序列值而不会冒标识符冲突的风险:

@Entity(name = "sequenceIdentifier")
public static class PooledLoSequenceIdentifier {@Id@GenericGenerator(name = "sequenceGenerator", strategy = "enhanced-sequence",parameters = {@org.hibernate.annotations.Parameter(name = "optimizer",value = "pooled-lo"),@org.hibernate.annotations.Parameter(name = "initial_value", value = "1"),@org.hibernate.annotations.Parameter(name = "increment_size", value = "5")})@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequenceGenerator")private Long id;
}

为了更好地了解此优化器的内部工作原理,下图总结了标识符分配过程:

合并循环优化器

结论

隐藏的宝石是大多数人甚至都不知道其存在的巨大功能之一。 pool-lo优化器非常有用,但是大多数人甚至都不知道它的存在。

  • 代码可在GitHub上获得 。

翻译自: https://www.javacodegeeks.com/2014/07/hibernate-hidden-gem-the-pooled-lo-optimizer.html

pooled-jms


http://chatgpt.dhexx.cn/article/xIRuRZ6l.shtml

相关文章

idea__MyBatis框架08——连接池(POOLED 跟 UNPOOLED )

一、继续上一节&#xff0c;把一些不用的注释给清理掉&#xff0c;看一下我们的mybatis主配置文件&#xff0c;重点看type。 二、Type详细介绍&#xff1a; mybatis连接池提供了3种方式的配置&#xff1a; type属性就是表示采用何种连接池方式。type属性的取值&#xff1a;POOL…

PODNet: Pooled Outputs Distillation for Small-Tasks Incremental Learning论文详解ECCV2020

ECCV2020 论文地址&#xff1a;https://doi.org/10.1007/978-3-030-58565_6 代码地址&#xff1a;https://github.com/arthurdouillard/incremental learning.pytorch 目录 1.贡献点 2.方法 2.1 pool类型 2.2 POD&#xff08;Pooled Outputs Distillation&#xff09;方…

mybatis数据源(JNDI、POOLED、UNPOOLED)源码详解

一、概述 二、创建 mybatis数据源的创建过程稍微有些曲折。 1. 数据源的创建过程&#xff1b; 2. mybatis支持哪些数据源&#xff0c;也就是dataSource标签的type属性可以写哪些合法的参数&#xff1f; 弄清楚这些问题&#xff0c;对mybatis的整个解析流程就清楚了&#xff0c;…

XAConnectionFactory: failed to create pooled connection - DBMS down or unreachable 的解决方法

问题描述 项目启动出现报错&#xff1a;XAConnectionFactory: failed to create pooled connection - DBMS down or unreachable? 原因分析&#xff1a; Druid连接池问题&#xff0c;当Druid与Atomikos搭配时&#xff0c;如果MySQL版本高于8.0.11则不被支持 查看数据库使用…

没有手动提交事务,Mybatis 的 POOLED 连接池炸了

错误原因&#xff1a; 事务不关&#xff0c;并且非事务交替进行 总的来说&#xff0c;就是先开启了事务连接&#xff0c;未提交或关闭&#xff0c;导致连接池连接全部占满。 此时进行一次非事务连接操作&#xff0c;但是因为此时已经没有可以空闲的连接&#xff0c;并且创建的连…

【Flink】报错 No pooled slot available and request to ResourceManager for new slot failed

文章目录 1.场景11.1 概述1.2 问题1.场景1 1.1 概述 改报错请参考:【Flink】Flink 1.9 升级 到 flink 1.12.4 报错 shaded netty4 AbstractChannel AnnotatedConnectException 错误描述 报错信息: java.util.concurrent.CompletionException:

Oracle 关于Pooled connection request timed out

发生场景&#xff1a; 系统异常卡死&#xff0c;报错&#xff1a; 通过查找日志和业务接口定位&#xff0c;是因为数据库连接池溢出导致链接不上&#xff0c;系统卡死 异常测试代码如下格式&#xff1a; 测试了一个1000次的链接&#xff0c;每次连接都持续30秒&#xff0c;链…

MyBatis POOLED连接池深入了解

往期内容&#xff0c;如下 一、MyBatis简介 二、MyBatis环境搭建 三、MyBatis入门案例 四、MyBatis自定义 五、MyBatis CRUD操作 六、Mybatis中参数和返回值的深入了解 七、MyBatis 配置文件标签 我们在实际开发中都会使用连接池&#xff0c;因为它可以减少我们获取连接所消耗的…

unpooled与pooled

unpooled每次都是重新获取一个连接&#xff0c;底层源码如下 pooled去判断有没有&#xff0c;有就拿出来用&#xff0c;没有就创建新的&#xff0c;每次用完再还回去 mybatis poolde连接池原理 先去看空闲的有没&#xff0c;有就直接用&#xff0c;没有就去活动连接池里把最老…

.NET性能优化-推荐使用Collections.Pooled

简介 性能优化就是如何在保证处理相同数量的请求情况下占用更少的资源&#xff0c;而这个资源一般就是CPU或者内存&#xff0c;当然还有操作系统IO句柄、网络流量、磁盘占用等等。但是绝大多数时候&#xff0c;我们就是在降低CPU和内存的占用率。 之前分享的内容都有一些局限性…

使用 TFDConnection 的 pooled 连接池

使用 TFDConnection 的 pooled 连接池 从开始看到这个属性&#xff0c;就一直认为他可以提供一个连接池管理功能&#xff0c; 苦于文档资料太少&#xff0c; 甚至在帮助中对该属性的使用都没有任何介绍&#xff0c;如果你搜索百度&#xff0c;也会发现基本没资料。 最后终于在…

Mybatis 连接池POOLED

1、连接池&#xff1a; 我们在实际开发中都会使用连接池。 因为它可以减少我们获取连接所消耗的时间。 2、mybatis中的连接池 在 Mybatis 中也有连接池技术&#xff0c;但是它采用的是自己的连接池技术。 在 Mybatis 的 SqlMapConfig.xml 配置文件中&#xff0c;通过来实 现 My…

Mybatis连接池介绍与分类 Mybatis使用POOLED UNPOOLED配置连接池的原理分析

一、连接池 1.概念&#xff1a;其实就是一个容器&#xff08;集合&#xff09;&#xff0c;存放数据库连接的容器。 当系统初始化好后&#xff0c;容器被创建&#xff0c;容器中会申请一些连接对象&#xff0c;当用户来访问数据库时&#xff0c;从容器中获取连接对象&#xf…

阶段3 1.Mybatis_07.Mybatis的连接池及事务_3 mybatis连接池的分类

2、mybatis中的连接池 mybatis连接池提供了3种方式的配置&#xff1a; 配置的位置&#xff1a; 主配置文件SqlMapConfig.xml中的dataSource标签&#xff0c;type属性就是表示采用何种连接池方式。 type属性的取值&#xff1a; POO…

Monkey Test简单介绍

什么是Monkey Test&#xff1f;顾名思义&#xff0c;就像一只猴子一样&#xff0c;它的下一步具有随机性。所以Monkey Test可以简单地理解为动作随机性测试&#xff01; Monkey是android模拟器或设备上运行的一个程序。它可以生成伪随机用户事件&#xff08;例如点击、触碰或滑…

monkey工具详解

第一部分&#xff1a;背景 1.为什么要开展压力测试&#xff1f; 提高产品的稳定性 提高产品的留存率 2.什么时候开始压力测试&#xff1f; 首轮功能测试通过后 下班后的夜间进行 第二部分&#xff1a;理论 1.什么是monkey&#xff1f; Monkey是发送伪随机用户事件的工…

monkey的基本使用

一、monkey介绍 1.功能&#xff1a;采用伪随机测试的方式&#xff0c;来完成app的稳定性测试 2.执行原理&#xff1a;通过monkey的shell脚本去执行安卓系统中自带的monkey.jar工具 3.通常用于盲测&#xff0c;压力测试和冒烟测试 1&#xff09;盲测&#xff1a;忽略功能和业务逻…

Monkey使用详解

App monkey 使用篇 安装包下载&#xff1a; 下载mumu模拟器地址&#xff1a;http://mumu.163.com/baidu/ 下载adb安装包 地 址&#xff1a;http://www.downza.cn/soft/219906.html Adb环境变量 配 置&#xff1a;在path里新建adb安装路径即可。 cmd 打开命令提示符窗口输入&a…

monkey的基本定义及基本使用(菜鸟学习中)

一.monkey的定义 1.(转自 https://blog.csdn.net/beyond_f/article/details/78543070 ) Monkey程序由Android系统自带&#xff0c;使用Java语言写成&#xff0c;在Android文件系统中的存放路径是&#xff1a;/system/framework/monkey.jar&#xff1b; Monkey.jar程序是由一…

Android测试--monkey详细到炸的总结

一、Monkey简介&#xff1a; Monkey是Android中的一个命令行工具&#xff0c;可以运行在模拟器里或者现实设备中&#xff0c;向系统发送伪随机的用户事件流&#xff08;点击、滑动、Application切换、横竖屏、应用关闭&#xff09;实现对正在开发的应用程序进行压力测试。monk…