Class Database
- Since:
- 1.0.0
- Author:
- Mark Allen
-
Nested Class Summary
Nested Classes -
Method Summary
Modifier and TypeMethodDescription@NonNull Optional<Transaction> Gets a reference to the current transaction, if any.@NonNull AmbiguousTimestampBindingStrategyHow should Pyranid bindInstantandOffsetDateTimeparameters when JDBC parameter metadata cannot identify whether the target isTIMESTAMPorTIMESTAMP WITH TIME ZONE?@NonNull DatabaseTypeGets the database type for this database.@NonNull MetricsCollector@NonNull ParameterRedactorGets the configured redactor used for non-secure parameters in diagnostics.@NonNull ZoneId@NonNull BooleanReports whether the configured database dialect and currently loadable runtime adapter expose the APIs required to attempt a notification-listening session.<T> @NonNull Optional<T> participate(@NonNull Transaction transaction, @NonNull ReturningTransactionalOperation<T> transactionalOperation) Performs an operation in the context of a pre-existing transaction, optionally returning a value.voidparticipate(@NonNull Transaction transaction, @NonNull TransactionalOperation transactionalOperation) Performs an operation in the context of a pre-existing transaction.voidperformHealthCheck(@NonNull Duration timeout) Performs a portable connectivity check using JDBCConnection.isValid(int).@NonNull QueryCreates a fluent builder for executing SQL.voidreadDatabaseMetaData(@NonNull DatabaseMetaDataReader databaseMetaDataReader) Exposes a temporary handle to JDBCDatabaseMetaData, which provides comprehensive vendor-specific information about this database as a whole.voidsendNotification(@NonNull String channel) Sends a transient database notification without specifying a payload.voidsendNotification(@NonNull String channel, @Nullable String payload) Sends a transient database notification.<T> @NonNull Optional<T> transaction(@NonNull ReturningTransactionalOperation<T> transactionalOperation) Performs an operation transactionally and optionally returns a value.voidtransaction(@NonNull TransactionalOperation transactionalOperation) Performs an operation transactionally.<T> @NonNull Optional<T> transaction(@NonNull TransactionOptions transactionOptions, @NonNull ReturningTransactionalOperation<T> transactionalOperation) Performs an operation transactionally with the given options, optionally returning a value.voidtransaction(@NonNull TransactionOptions transactionOptions, @NonNull TransactionalOperation transactionalOperation) Performs an operation transactionally with the given options.<T> @NonNull TransactionRetryResult<T> transactionWithRetry(@NonNull RetryPolicy retryPolicy, @NonNull ReturningTransactionalOperation<T> transactionalOperation) Performs an operation transactionally and optionally returns a value, retrying according to the given retry policy.@NonNull TransactionRetryResult<Void> transactionWithRetry(@NonNull RetryPolicy retryPolicy, @NonNull TransactionalOperation transactionalOperation) Performs an operation transactionally, retrying according to the given retry policy.<T> @NonNull TransactionRetryResult<T> transactionWithRetry(@NonNull RetryPolicy retryPolicy, @NonNull TransactionOptions transactionOptions, @NonNull ReturningTransactionalOperation<T> transactionalOperation) Performs an operation transactionally with the given options and optionally returns a value, retrying according to the given retry policy.@NonNull TransactionRetryResult<Void> transactionWithRetry(@NonNull RetryPolicy retryPolicy, @NonNull TransactionOptions transactionOptions, @NonNull TransactionalOperation transactionalOperation) Performs an operation transactionally with the given options, retrying according to the given retry policy.<T> @NonNull Optional<T> useRawConnection(@NonNull RawConnectionOperation<T> rawConnectionOperation) Performs raw JDBC work with a Pyranid-managedConnection.static @NonNull Database.BuilderwithDataSource(@NonNull DataSource dataSource) Provides aDatabasebuilder for the givenDataSource.voidwithNotificationSession(@NonNull String channel, @NonNull NotificationSessionOperation operation) Performs an operation with one callback-scoped database-notification listener session for a single channel.voidwithNotificationSession(@NonNull Set<@NonNull String> channels, @NonNull NotificationSessionOperation operation) Performs an operation with one callback-scoped database-notification listener session.
-
Method Details
-
withDataSource
Provides aDatabasebuilder for the givenDataSource. -
currentTransaction
Gets a reference to the current transaction, if any.- Returns:
- the current transaction
-
transaction
Performs an operation transactionally.The transaction will be automatically rolled back if an exception bubbles out of
transactionalOperation.Nested calls to
transaction(...)are independent transactions with independent JDBC connections; they do not automatically join an outer transaction. Useparticipate(Transaction, TransactionalOperation)to join an existing transaction explicitly. A transaction is scoped to theDataSourceinstance that created it; aDatabaseusing a differentDataSourcefails fast instead of joining it.- Parameters:
transactionalOperation- the operation to perform transactionally
-
transaction
public void transaction(@NonNull TransactionOptions transactionOptions, @NonNull TransactionalOperation transactionalOperation) Performs an operation transactionally with the given options.The transaction will be automatically rolled back if an exception bubbles out of
transactionalOperation.Nested calls to
transaction(...)are independent transactions with independent JDBC connections; they do not automatically join an outer transaction. Useparticipate(Transaction, TransactionalOperation)to join an existing transaction explicitly. A transaction is scoped to theDataSourceinstance that created it; aDatabaseusing a differentDataSourcefails fast instead of joining it.- Parameters:
transactionOptions- options to apply to the transactiontransactionalOperation- the operation to perform transactionally- Since:
- 4.2.0
-
transaction
public <T> @NonNull Optional<T> transaction(@NonNull ReturningTransactionalOperation<T> transactionalOperation) Performs an operation transactionally and optionally returns a value.The transaction will be automatically rolled back if an exception bubbles out of
transactionalOperation.Nested calls to
transaction(...)are independent transactions with independent JDBC connections; they do not automatically join an outer transaction. Useparticipate(Transaction, ReturningTransactionalOperation)to join an existing transaction explicitly. A transaction is scoped to theDataSourceinstance that created it; aDatabaseusing a differentDataSourcefails fast instead of joining it.- Type Parameters:
T- the type to be returned- Parameters:
transactionalOperation- the operation to perform transactionally- Returns:
- the result of the transactional operation
-
transaction
public <T> @NonNull Optional<T> transaction(@NonNull TransactionOptions transactionOptions, @NonNull ReturningTransactionalOperation<T> transactionalOperation) Performs an operation transactionally with the given options, optionally returning a value.The transaction will be automatically rolled back if an exception bubbles out of
transactionalOperation.Nested calls to
transaction(...)are independent transactions with independent JDBC connections; they do not automatically join an outer transaction. Useparticipate(Transaction, ReturningTransactionalOperation)to join an existing transaction explicitly. A transaction is scoped to theDataSourceinstance that created it; aDatabaseusing a differentDataSourcefails fast instead of joining it.- Type Parameters:
T- the type to be returned- Parameters:
transactionOptions- options to apply to the transactiontransactionalOperation- the operation to perform transactionally- Returns:
- the result of the transactional operation
- Since:
- 4.2.0
-
transactionWithRetry
public @NonNull TransactionRetryResult<Void> transactionWithRetry(@NonNull RetryPolicy retryPolicy, @NonNull TransactionalOperation transactionalOperation) Performs an operation transactionally, retrying according to the given retry policy.The entire transaction closure may run more than once. Keep non-idempotent external side effects outside the closure unless they are safe to repeat.
Pyranid consults the retry policy only after the database outcome is known to be rolled back. This includes a recognized serialization failure reported by physical commit when the follow-up rollback succeeds. Other commit failures and all rollback failures are terminal because their outcome is indeterminate.
Unlike
transaction(TransactionalOperation)and related transaction methods, retrying methods returnTransactionRetryResultso callers can inspect failures that were recovered before success.This method fails fast if called inside an active transaction for this
Database. Retrying a nested unit cannot restart the outer transaction safely.- Parameters:
retryPolicy- retry policy to applytransactionalOperation- the operation to perform transactionally- Returns:
- retry result containing any failures retried before success
- Since:
- 4.4.0
-
transactionWithRetry
public @NonNull TransactionRetryResult<Void> transactionWithRetry(@NonNull RetryPolicy retryPolicy, @NonNull TransactionOptions transactionOptions, @NonNull TransactionalOperation transactionalOperation) Performs an operation transactionally with the given options, retrying according to the given retry policy.The entire transaction closure may run more than once. Keep non-idempotent external side effects outside the closure unless they are safe to repeat.
Pyranid consults the retry policy only after the database outcome is known to be rolled back. This includes a recognized serialization failure reported by physical commit when the follow-up rollback succeeds. Other commit failures and all rollback failures are terminal because their outcome is indeterminate.
Unlike
transaction(TransactionOptions, TransactionalOperation)and related transaction methods, retrying methods returnTransactionRetryResultso callers can inspect failures that were recovered before success.This method fails fast if called inside an active transaction for this
Database. Retrying a nested unit cannot restart the outer transaction safely.- Parameters:
retryPolicy- retry policy to applytransactionOptions- options to apply to each transaction attempttransactionalOperation- the operation to perform transactionally- Returns:
- retry result containing any failures retried before success
- Since:
- 4.4.0
-
transactionWithRetry
public <T> @NonNull TransactionRetryResult<T> transactionWithRetry(@NonNull RetryPolicy retryPolicy, @NonNull ReturningTransactionalOperation<T> transactionalOperation) Performs an operation transactionally and optionally returns a value, retrying according to the given retry policy.The entire transaction closure may run more than once. Keep non-idempotent external side effects outside the closure unless they are safe to repeat.
Pyranid consults the retry policy only after the database outcome is known to be rolled back. This includes a recognized serialization failure reported by physical commit when the follow-up rollback succeeds. Other commit failures and all rollback failures are terminal because their outcome is indeterminate.
Unlike
transaction(ReturningTransactionalOperation)and related transaction methods, retrying methods returnTransactionRetryResultso callers can inspect failures that were recovered before success.This method fails fast if called inside an active transaction for this
Database. Retrying a nested unit cannot restart the outer transaction safely.- Type Parameters:
T- the type to be returned- Parameters:
retryPolicy- retry policy to applytransactionalOperation- the operation to perform transactionally- Returns:
- retry result containing the successful transaction value and any failures retried before success
- Since:
- 4.4.0
-
transactionWithRetry
public <T> @NonNull TransactionRetryResult<T> transactionWithRetry(@NonNull RetryPolicy retryPolicy, @NonNull TransactionOptions transactionOptions, @NonNull ReturningTransactionalOperation<T> transactionalOperation) Performs an operation transactionally with the given options and optionally returns a value, retrying according to the given retry policy.The entire transaction closure may run more than once. Keep non-idempotent external side effects outside the closure unless they are safe to repeat.
Pyranid consults the retry policy only after the database outcome is known to be rolled back. This includes a recognized serialization failure reported by physical commit when the follow-up rollback succeeds. Other commit failures and all rollback failures are terminal because their outcome is indeterminate.
Unlike
transaction(TransactionOptions, ReturningTransactionalOperation)and related transaction methods, retrying methods returnTransactionRetryResultso callers can inspect failures that were recovered before success.This method fails fast if called inside an active transaction for this
Database. Retrying a nested unit cannot restart the outer transaction safely.- Type Parameters:
T- the type to be returned- Parameters:
retryPolicy- retry policy to applytransactionOptions- options to apply to each transaction attempttransactionalOperation- the operation to perform transactionally- Returns:
- retry result containing the successful transaction value and any failures retried before success
- Since:
- 4.4.0
-
participate
public void participate(@NonNull Transaction transaction, @NonNull TransactionalOperation transactionalOperation) Performs an operation in the context of a pre-existing transaction.No commit or rollback on the transaction will occur when
transactionalOperationcompletes.However, if an exception bubbles out of
transactionalOperation, the transaction will be marked as rollback-only.The transaction must have been created by this
Database, or by anotherDatabaseusing the sameDataSourceinstance.If this thread is interrupted while waiting for another participant to release the transaction connection, Pyranid restores the interrupt flag and throws
DatabaseException.- Parameters:
transaction- the transaction in which to participatetransactionalOperation- the operation that should participate in the transaction
-
participate
public <T> @NonNull Optional<T> participate(@NonNull Transaction transaction, @NonNull ReturningTransactionalOperation<T> transactionalOperation) Performs an operation in the context of a pre-existing transaction, optionally returning a value.No commit or rollback on the transaction will occur when
transactionalOperationcompletes.However, if an exception bubbles out of
transactionalOperation, the transaction will be marked as rollback-only.The transaction must have been created by this
Database, or by anotherDatabaseusing the sameDataSourceinstance.If this thread is interrupted while waiting for another participant to release the transaction connection, Pyranid restores the interrupt flag and throws
DatabaseException.- Type Parameters:
T- the type to be returned- Parameters:
transaction- the transaction in which to participatetransactionalOperation- the operation that should participate in the transaction- Returns:
- the result of the transactional operation
-
query
Creates a fluent builder for executing SQL.Named parameters use the
:paramNamesyntax and are bound viaQuery.bind(String, Object). Positional parameters via?are not supported. Pyranid ignores parameter-looking text inside SQL string literals, quoted identifiers, comments, PostgreSQL dollar-quoted strings, and SQL Server-style bracket-quoted identifiers. PostgreSQL JSONB/hstore?,?|, and?&operators are supported; when running againstDatabaseType.POSTGRESQL, Pyranid emits pgjdbc's escaped??form automatically. Unterminated quotes and comments fail fast.Example:
Optional<Employee> employee = database.query("SELECT * FROM employee WHERE id = :id") .bind("id", 42) .fetchObject(Employee.class);- Parameters:
sql- SQL containing:paramNameplaceholders- Returns:
- a fluent builder for binding parameters and executing
- Since:
- 4.0.0
-
performHealthCheck
Performs a portable connectivity check using JDBCConnection.isValid(int).This method borrows a fresh connection from this database's
DataSource, callsConnection.isValid(int), and closes the connection before returning. It does not participate in an active Pyranid transaction, if one exists.JDBC accepts timeout values in whole seconds. Positive sub-second durations are rounded up to one second;
Duration.ZEROpasses a timeout of0to the driver.- Parameters:
timeout- maximum time to wait for driver validation- Throws:
IllegalArgumentException- iftimeoutis negative or too large for JDBC's integer-second timeoutDatabaseException- if connection acquisition fails, validation throws, or the driver reports the connection is not valid- Since:
- 4.2.0
-
readDatabaseMetaData
Exposes a temporary handle to JDBCDatabaseMetaData, which provides comprehensive vendor-specific information about this database as a whole.This method acquires
DatabaseMetaDataon its own newly-borrowed connection, which it manages internally.It does not participate in the active transaction, if one exists.
The connection is closed as soon as
DatabaseMetaDataReader.read(DatabaseMetaData)completes.See
DatabaseMetaDataJavadoc for details. -
useRawConnection
public <T> @NonNull Optional<T> useRawConnection(@NonNull RawConnectionOperation<T> rawConnectionOperation) Performs raw JDBC work with a Pyranid-managedConnection.If called inside a Pyranid transaction, this operation uses the transaction's connection and participates in that transaction. Otherwise, Pyranid borrows a connection for the duration of the callback and closes it afterwards.
The
Connectionpassed torawConnectionOperationis a guarded handle. Normal JDBC operations are delegated to the underlying driver connection, but lifecycle, transaction-management, and connection-wide state methods such asConnection.close(),Connection.commit(),Connection.rollback(),Connection.setAutoCommit(boolean),Connection.setCatalog(String),Connection.setSchema(String), andConnection.setNetworkTimeout(java.util.concurrent.Executor, int)throwIllegalStateException. Use Pyranid transaction APIs instead.Wrapper.unwrap(Class)may return a guarded, callback-scoped proxy for a vendor interface, but never a castable physicalConnection; the proxy blocks lifecycle methods and expires with the callback. JDBC objects created from this handle are also guarded:Statement.getConnection()andDatabaseMetaData.getConnection()return the Pyranid-managed handle, andResultSet.getStatement()returns a guarded statement. Guarded statements, resultsets, and metadata refuse driver-specificunwrap(...)calls that could expose the driver's underlying connection.The connection handle is valid only for the duration of the callback. Do not close it, retain it, or use it after this method returns.
- Type Parameters:
T- the type to be returned- Parameters:
rawConnectionOperation- the raw JDBC operation to perform- Returns:
- the operation result
- Throws:
DatabaseException- if connection acquisition, callback execution, or cleanup fails- Since:
- 4.2.0
-
withNotificationSession
public void withNotificationSession(@NonNull Set<@NonNull String> channels, @NonNull NotificationSessionOperation operation) throws InterruptedException Performs an operation with one callback-scoped database-notification listener session.This method is synchronous and blocking. It acquires at most one listener connection from this
Database's configuredDataSource, registers every requested channel, invokesoperationat most once, expires the suppliedNotificationSession, and completes cleanup before returning or throwing. It never reconnects.The configured source must preserve one physical backend session for the entire checkout. For PostgreSQL, direct connections and session pooling are suitable. Using PgBouncer transaction or statement pooling as the listener source is unsupported: registration can appear to succeed before backend-session affinity is lost and notification delivery silently stops. Pyranid does not inspect or validate proxy topology. Applications whose ordinary source cannot provide the required affinity should construct a separate
Databaseover a suitable listener source and invoke this method on that instance.Notifications are lossy hints. Durable applications should normally reconcile authoritative state as the first callback action. The operation may use ordinary database methods, but those methods acquire or select their connection normally and never reuse the listener connection.
A terminal receive failure is retained by the session and rethrown after cleanup even if
operationcatches it and returns. A retained transportErrorpropagates as that exact, unwrapped instance. If the callback instead throws a distinctError, that callback error remains primary and the retained transport failure is suppressed beneath it.- Parameters:
channels- fixed, nonempty set of nonblank channels to registeroperation- operation to invoke after every channel has been registered- Throws:
NullPointerException- ifchannels, a channel, oroperationis nullIllegalArgumentException- if the set is empty or a channel violates common or backend-specific limitsIllegalStateException- if any Pyranid transaction is active on the calling threadInterruptedException- if cooperative interruption wins after any required cleanupUnsupportedOperationException- if the database dialect or runtime driver cannot receive notificationsDatabaseException- if connection acquisition, setup, receive, callback execution, or cleanup fails- Since:
- 4.6.0
-
withNotificationSession
public void withNotificationSession(@NonNull String channel, @NonNull NotificationSessionOperation operation) throws InterruptedException Performs an operation with one callback-scoped database-notification listener session for a single channel.This is the single-channel convenience form of
withNotificationSession(Set, NotificationSessionOperation). The listener connection comes from thisDatabase's configuredDataSource, which must preserve physical backend-session affinity for the entire checkout. For PostgreSQL, using PgBouncer transaction or statement pooling as the listener source is unsupported: registration can appear to succeed before affinity is lost and delivery silently stops. Pyranid does not inspect or validate proxy topology.A terminal receive failure is retained and rethrown after cleanup even if
operationcatches it and returns. A retained transportErrorpropagates as the exact, unwrapped instance unless a distinct callbackErrortakes precedence as described by the set-based overload.- Parameters:
channel- nonblank channel to registeroperation- operation to invoke after the channel has been registered- Throws:
NullPointerException- ifchanneloroperationis nullIllegalArgumentException- if the channel violates common or backend-specific limitsIllegalStateException- if any Pyranid transaction is active on the calling threadInterruptedException- if cooperative interruption wins after any required cleanupUnsupportedOperationException- if the database dialect or runtime driver cannot receive notificationsDatabaseException- if connection acquisition, setup, receive, callback execution, or cleanup fails- Since:
- 4.6.0
-
sendNotification
Sends a transient database notification without specifying a payload.Sending follows ordinary Pyranid statement and transaction selection. On PostgreSQL, a send inside a Pyranid transaction becomes visible only if that transaction commits. Payload representation is database-specific; PostgreSQL converts the resulting null payload to the empty string.
- Parameters:
channel- nonblank notification channel- Throws:
NullPointerException- ifchannelis nullIllegalArgumentException- if the channel violates common or backend-specific limitsUnsupportedOperationException- if the database dialect does not support notification sendsDatabaseException- if the send fails- Since:
- 4.6.0
-
sendNotification
Sends a transient database notification.Sending follows ordinary Pyranid statement and transaction selection, including connection ownership, parameter binding and redaction, statement logging, timeout configuration, and metrics. Payload nullability and null/empty-string handling are database-specific; Pyranid performs no generic normalization.
On PostgreSQL this executes bound
pg_notify(?, ?)SQL. PostgreSQL converts a null payload to the empty string. Delivery occurs only after commit and is discarded by rollback; notification delivery itself remains non-durable and may be coalesced.- Parameters:
channel- nonblank notification channelpayload- notification payload, possibly null or empty- Throws:
NullPointerException- ifchannelis nullIllegalArgumentException- if the channel or payload violates common or backend-specific limitsUnsupportedOperationException- if the database dialect does not support notification sendsDatabaseException- if the send fails- Since:
- 4.6.0
-
isNotificationListeningSupported
Reports whether the configured database dialect and currently loadable runtime adapter expose the APIs required to attempt a notification-listening session.This method resolves the full database type. If it has not been configured or cached, resolution may acquire a metadata connection and may throw
DatabaseException. It does not acquire a listener session, inspect pool or proxy mode, prove backend-session affinity, unwrap a physical listener connection, or emit notification-session lifecycle metrics.- Returns:
- true if notification listening can be attempted with the current dialect and runtime
- Throws:
DatabaseException- if automatic database-type detection fails- Since:
- 4.6.0
-
getDatabaseType
Gets the database type for this database.If
Database.Builder.databaseType(DatabaseType)was not configured and the database type has not already been detected, this method may acquire a connection and inspectDatabaseMetaData. Configure an explicit database type to avoid runtime detection.- Returns:
- the database type
- Throws:
DatabaseException- if automatic database type detection fails- Since:
- 3.0.0
-
getTimeZone
- Since:
- 3.0.0
-
getAmbiguousTimestampBindingStrategy
How should Pyranid bindInstantandOffsetDateTimeparameters when JDBC parameter metadata cannot identify whether the target isTIMESTAMPorTIMESTAMP WITH TIME ZONE?- Returns:
- behavior to use when timestamp target metadata is unavailable or non-identifying
- Since:
- 4.2.0
-
getParameterRedactor
Gets the configured redactor used for non-secure parameters in diagnostics.- Returns:
- the configured parameter redactor
- Since:
- 4.4.0
-
getMetricsCollector
-