高端旅游定制网站,一般网站维护要多久,长沙网页设计培训班,wordpress新建用户组pooled-jms介绍 在这篇文章中#xff0c;我们将揭示一个序列标识符生成器#xff0c;它结合了标识符分配效率和与其他外部系统的互操作性#xff08;同时访问底层数据库系统#xff09;。 传统上#xff0c;有两种序列标识符策略可供选择。 序列标识符#xff0c;对… pooled-jms 介绍 在这篇文章中我们将揭示一个序列标识符生成器它结合了标识符分配效率和与其他外部系统的互操作性同时访问底层数据库系统。 传统上有两种序列标识符策略可供选择。 序列标识符对于每个新值分配总是命中数据库。 即使使用数据库序列预分配我们也要花费大量的数据库往返费用。 seqhilo标识符使用hi / lo算法。 该生成器在内存中计算一些标识符值因此减少了数据库往返调用。 这种优化技术的问题在于当前的数据库序列值不再反映当前的最高内存生成值。 数据库序列用作存储区编号因此其他系统很难与所讨论的数据库表进行互操作。 其他应用程序必须知道高/低标识符策略的内部工作方式才能正确生成非冲突标识符。 增强的标识符 Hibernate提供了一类新的标识符生成器 解决了原始标识符生成器的许多缺点。 增强的标识符生成器没有固定的标识符分配策略。 优化策略是可配置的我们甚至可以提供自己的优化实现。 默认情况下Hibernate随附以下内置优化器 none 每个标识符都是从数据库中获取的因此等效于原始序列生成器。 hi / lo 它使用hi / lo算法与原始seqhilo生成器等效。 合并的 此优化器使用高/低优化策略但是当前内存中标识符的最高边界是从实际数据库序列值中提取的。 pooled-lo 它类似于池优化器但是数据库序列值用作当前内存中的最低边界 在正式发布公告中 公告了合并的优化器可与其他外部系统进行互操作 即使其他应用程序也在插入值我们也将是绝对安全的因为SEQUENCE本身将处理应用此增量大小。 这实际上是我们正在寻找的东西。 当其他外部系统在同一数据库表中同时插入行时标识符生成器既高效又不会冲突。 测试时间 以下测试将检查新的优化器如何与其他外部数据库表插入配合使用。 在我们的例子中外部系统将是在同一数据库表/序列上的一些本机JDBC插入语句。 doInTransaction(new TransactionCallableVoid() {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());ListNumber 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 {IdGenericGenerator(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 {IdGenericGenerator(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.htmlpooled-jms