From b7a8f4940e0b2db3e2a34b851bc3eec704a4337d Mon Sep 17 00:00:00 2001 From: Gavin Date: Fri, 12 May 2023 18:02:56 +0200 Subject: [PATCH] pool configuration --- .../asciidoc/introduction/Configuration.adoc | 16 +++-- .../main/asciidoc/introduction/Tuning.adoc | 59 ++++++++++++++++--- ...edDriverManagerConnectionProviderImpl.java | 2 +- 3 files changed, 64 insertions(+), 13 deletions(-) diff --git a/documentation/src/main/asciidoc/introduction/Configuration.adoc b/documentation/src/main/asciidoc/introduction/Configuration.adoc index 07c2306f5d..6701193d26 100644 --- a/documentation/src/main/asciidoc/introduction/Configuration.adoc +++ b/documentation/src/main/asciidoc/introduction/Configuration.adoc @@ -228,9 +228,9 @@ The properties you really do need to get started are these three: .JDBC connection settings [cols=",2"] |=== -| Configuration property name | Purpose +| Configuration property name | Purpose -| `jakarta.persistence.jdbc.url` | JDBC URL of your database +| `jakarta.persistence.jdbc.url` | JDBC URL of your database | `jakarta.persistence.jdbc.user` and `jakarta.persistence.jdbc.password` | Your database credentials |=== @@ -244,13 +244,21 @@ The only reason to specify this property is if you're using a custom user-writte ==== Pooling JDBC connections is an extremely important performance optimization. -You can set the size of Hibernate's built-in connection pool using the property `hibernate.connection.pool_size`. +You can set the size of Hibernate's built-in connection pool using this property: + +.Built-in connection pool size +[cols=",2"] +|=== +| Configuration property name | Purpose + +| `hibernate.connection.pool_size` | The size of the built-in connection pool +|=== [CAUTION] .The default connection pool is not meant for production use ==== By default, Hibernate uses a simplistic built-in connection pool. -This pool is not meant for use in production, and later, when we discuss performance, we'll see how to select a more robust implementation. +This pool is not meant for use in production, and later, when we discuss performance, we'll see how to <>. ==== Alternatively, in a container environment, you'll need at least one of these properties: diff --git a/documentation/src/main/asciidoc/introduction/Tuning.adoc b/documentation/src/main/asciidoc/introduction/Tuning.adoc index 6fc788ad5e..b0f0d8bdca 100644 --- a/documentation/src/main/asciidoc/introduction/Tuning.adoc +++ b/documentation/src/main/asciidoc/introduction/Tuning.adoc @@ -32,26 +32,68 @@ the connection pool. [[connection-pool]] === Tuning the connection pool -TODO +The connection pool built in to Hibernate is suitable for testing, but isn't intended for use in production. +Instead, Hibernate supports a range of different connection pools, including our favorite, Agroal. + +To select and configure Agroal, you'll need to set some extra configuration properties, in addition to the settings we already saw in <>. +For example: + +[source,properties] +---- +hibernate.agroal.maxSize 20 +hibernate.agroal.minSize 10 +hibernate.agroal.acquisitionTimeout PT1s +hibernate.agroal.reapTimeout PT10s +---- + +As long as you set at least one property with the prefix `hibernate.agroal`, the `AgroalConnectionProvider` will be selected automatically. + +.Settings for configuring Agroal +[cols=",4"] +|=== +| Configuration property name | Purpose + +| `hibernate.agroal.maxSize` | The maximum number of connections present on the pool +| `hibernate.agroal.minSize` | The minimum number of connections present on the pool +| `hibernate.agroal.initialSize` | The number of connections added to the pool when it is started +| `hibernate.agroal.maxLifetime` | The maximum amount of time a connection can live, after which it is removed from the pool +| `hibernate.agroal.acquisitionTimeout` | The maximum amount of time a thread can wait for a connection, after which an exception is thrown instead +| `hibernate.agroal.reapTimeout` | The duration for eviction of idle connections +| `hibernate.agroal.leakTimeout` | The duration of time a connection can be held without causing a leak to be reported +| `hibernate.agroal.idleValidationTimeout` | A foreground validation is executed if a connection has been idle on the pool for longer than this duration +| `hibernate.agroal.validationTimeout` | The interval between background validation checks +| `hibernate.agroal.initialSql` | A SQL command to be executed when a connection is created +| `hibernate.connection.autocommit` | The default autocommit mode +| `hibernate.connection.isolation` | The default transaction isolation level +|=== + +[NOTE] +.This is not needed in a container environment +==== +In a container environment, you usually don't need to configure a connection pool through Hibernate. +Instead, you'll use a container-managed datasource, as we saw in <>. +==== [[statement-batching]] === Enabling statement batching -An easy way to improve performance of some transactions with almost no -work at all is to turn on automatic DML statement batching. Batching -only helps in cases where a program executes many inserts, updates, or -deletes against the same table in a single transaction. +An easy way to improve performance of some transactions, with almost no work at all, is to turn on automatic DML statement batching. +Batching only helps in cases where a program executes many inserts, updates, or deletes against the same table in a single transaction. All you need to do is set a single property: +.Enabling JDBC batching +[cols=",3"] |=== | Configuration property name | Purpose | `hibernate.jdbc.batch_size` | Maximum batch size for SQL statement batching |=== -TIP: Even better than DML statement batching is the use of HQL `update` -or `delete` queries, or even native SQL that calls a stored procedure! +[TIP] +==== +Even better than DML statement batching is the use of HQL `update` or `delete` queries, or even native SQL that calls a stored procedure! +==== [[association-fetching]] === Association fetching @@ -129,7 +171,8 @@ By nature, a second-level cache tends to undermine the ACID properties of transa Therefore, by default, an entity is not eligible for storage in the second-level cache. We must explicitly mark each entity that will be stored in the second-level cache with the `@Cache` annotation from `org.hibernate.annotations`. -But that's still not enough: Hibernate does not itself contain an implementation of a second-level cache, so it's necessary to configure an external _cache provider_. +But that's still not enough. +Hibernate does not itself contain an implementation of a second-level cache, so it's necessary to configure an external _cache provider_. ==== Hibernate segments the second-level cache into named _regions_, one for each: diff --git a/hibernate-testing/src/main/java/org/hibernate/testing/jdbc/SharedDriverManagerConnectionProviderImpl.java b/hibernate-testing/src/main/java/org/hibernate/testing/jdbc/SharedDriverManagerConnectionProviderImpl.java index afb67e9b1e..a010097ba6 100644 --- a/hibernate-testing/src/main/java/org/hibernate/testing/jdbc/SharedDriverManagerConnectionProviderImpl.java +++ b/hibernate-testing/src/main/java/org/hibernate/testing/jdbc/SharedDriverManagerConnectionProviderImpl.java @@ -88,7 +88,7 @@ public class SharedDriverManagerConnectionProviderImpl extends DriverManagerConn private final Integer isolation; public Config(Map configurationValues) { - this.autoCommit = ConfigurationHelper.getBoolean( AvailableSettings.AUTOCOMMIT, configurationValues, false ); + this.autoCommit = ConfigurationHelper.getBoolean( AvailableSettings.AUTOCOMMIT, configurationValues ); this.minSize = ConfigurationHelper.getInt( MIN_SIZE, configurationValues, 0 ); this.maxSize = ConfigurationHelper.getInt( AvailableSettings.POOL_SIZE, configurationValues, 20 ); this.initialSize = ConfigurationHelper.getInt( INITIAL_SIZE, configurationValues, minSize );