clean up the JdbcSessionContext SPI + related code
- encapsulate stuff better within JdbcSessionContext - fix lots of warnings - deprecate stuff
This commit is contained in:
parent
689cca1963
commit
366208924f
|
@ -1133,7 +1133,7 @@ public class SessionFactoryOptionsBuilder implements SessionFactoryOptions {
|
|||
|
||||
@Override
|
||||
public boolean isPreferUserTransaction() {
|
||||
return this.preferUserTransaction;
|
||||
return preferUserTransaction;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -2180,7 +2180,7 @@ public interface AvailableSettings {
|
|||
* transaction timeout handled by a background reaper thread. The ability
|
||||
* to handle this situation requires checking the Thread ID every time
|
||||
* Session is called. This can certainly have performance considerations.
|
||||
*
|
||||
* <p>
|
||||
* Default is {@code true} (enabled).
|
||||
*
|
||||
* @see org.hibernate.boot.SessionFactoryBuilder#applyJtaTrackingByThread(boolean)
|
||||
|
|
|
@ -68,11 +68,7 @@ public class BatchImpl implements Batch {
|
|||
this.jdbcCoordinator = jdbcCoordinator;
|
||||
this.statementGroup = statementGroup;
|
||||
|
||||
final JdbcServices jdbcServices = jdbcCoordinator.getJdbcSessionOwner()
|
||||
.getJdbcSessionContext()
|
||||
.getSessionFactory()
|
||||
.getFastSessionServices().jdbcServices;
|
||||
|
||||
final JdbcServices jdbcServices = jdbcCoordinator.getJdbcSessionOwner().getJdbcSessionContext().getJdbcServices();
|
||||
this.sqlStatementLogger = jdbcServices.getSqlStatementLogger();
|
||||
this.sqlExceptionHelper = jdbcServices.getSqlExceptionHelper();
|
||||
|
||||
|
|
|
@ -19,9 +19,7 @@ import org.hibernate.ConnectionReleaseMode;
|
|||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.TransactionException;
|
||||
import org.hibernate.engine.jdbc.batch.spi.Batch;
|
||||
import org.hibernate.engine.jdbc.batch.spi.BatchBuilder;
|
||||
import org.hibernate.engine.jdbc.batch.spi.BatchKey;
|
||||
import org.hibernate.engine.jdbc.connections.spi.JdbcConnectionAccess;
|
||||
import org.hibernate.engine.jdbc.mutation.group.PreparedStatementGroup;
|
||||
import org.hibernate.engine.jdbc.spi.InvalidatableWrapper;
|
||||
import org.hibernate.engine.jdbc.spi.JdbcCoordinator;
|
||||
|
@ -31,7 +29,6 @@ import org.hibernate.engine.jdbc.spi.MutationStatementPreparer;
|
|||
import org.hibernate.engine.jdbc.spi.ResultSetReturn;
|
||||
import org.hibernate.engine.jdbc.spi.SqlExceptionHelper;
|
||||
import org.hibernate.engine.jdbc.spi.StatementPreparer;
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.internal.CoreLogging;
|
||||
import org.hibernate.internal.CoreMessageLogger;
|
||||
import org.hibernate.jdbc.WorkExecutor;
|
||||
|
@ -44,6 +41,8 @@ import org.hibernate.resource.jdbc.spi.JdbcSessionOwner;
|
|||
import org.hibernate.resource.jdbc.spi.LogicalConnectionImplementor;
|
||||
import org.hibernate.resource.transaction.backend.jdbc.spi.JdbcResourceTransaction;
|
||||
|
||||
import static org.hibernate.ConnectionReleaseMode.AFTER_STATEMENT;
|
||||
|
||||
/**
|
||||
* Standard implementation of {@link JdbcCoordinator}.
|
||||
*
|
||||
|
@ -72,7 +71,7 @@ public class JdbcCoordinatorImpl implements JdbcCoordinator {
|
|||
private boolean releasesEnabled = true;
|
||||
|
||||
/**
|
||||
* Constructs a JdbcCoordinatorImpl
|
||||
* Constructs a {@code JdbcCoordinatorImpl}
|
||||
*
|
||||
* @param userSuppliedConnection The user supplied connection (may be null)
|
||||
*/
|
||||
|
@ -107,9 +106,7 @@ public class JdbcCoordinatorImpl implements JdbcCoordinator {
|
|||
this.logicalConnection = logicalConnection;
|
||||
this.isUserSuppliedConnection = isUserSuppliedConnection;
|
||||
this.owner = owner;
|
||||
this.jdbcServices = owner.getJdbcSessionContext()
|
||||
.getServiceRegistry()
|
||||
.getService( JdbcServices.class );
|
||||
this.jdbcServices = owner.getJdbcSessionContext().getJdbcServices();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -117,14 +114,10 @@ public class JdbcCoordinatorImpl implements JdbcCoordinator {
|
|||
return logicalConnection;
|
||||
}
|
||||
|
||||
protected SessionFactoryImplementor sessionFactory() {
|
||||
return this.owner.getJdbcSessionContext().getSessionFactory();
|
||||
}
|
||||
|
||||
/**
|
||||
* Access to the SqlExceptionHelper
|
||||
* Access to the {@link SqlExceptionHelper}
|
||||
*
|
||||
* @return The SqlExceptionHelper
|
||||
* @return The {@code SqlExceptionHelper}
|
||||
*/
|
||||
public SqlExceptionHelper sqlExceptionHelper() {
|
||||
return jdbcServices.getSqlExceptionHelper();
|
||||
|
@ -181,8 +174,8 @@ public class JdbcCoordinatorImpl implements JdbcCoordinator {
|
|||
}
|
||||
}
|
||||
|
||||
final BatchBuilder batchBuilder = sessionFactory().getFastSessionServices().batchBuilder;
|
||||
currentBatch = batchBuilder.buildBatch( key, batchSize, statementGroupSupplier, this );
|
||||
currentBatch = owner.getJdbcSessionContext().getBatchBuilder()
|
||||
.buildBatch( key, batchSize, statementGroupSupplier, this );
|
||||
|
||||
return currentBatch;
|
||||
}
|
||||
|
@ -262,7 +255,7 @@ public class JdbcCoordinatorImpl implements JdbcCoordinator {
|
|||
public void afterStatementExecution() {
|
||||
final ConnectionReleaseMode connectionReleaseMode = getLogicalConnection().getConnectionHandlingMode().getReleaseMode();
|
||||
LOG.tracev( "Starting after statement execution processing [{0}]", connectionReleaseMode );
|
||||
if ( connectionReleaseMode == ConnectionReleaseMode.AFTER_STATEMENT ) {
|
||||
if ( connectionReleaseMode == AFTER_STATEMENT ) {
|
||||
if ( ! releasesEnabled ) {
|
||||
LOG.debug( "Skipping aggressive release due to manual disabling" );
|
||||
return;
|
||||
|
@ -278,38 +271,18 @@ public class JdbcCoordinatorImpl implements JdbcCoordinator {
|
|||
@Override
|
||||
public void afterTransaction() {
|
||||
transactionTimeOutInstant = -1;
|
||||
ConnectionReleaseMode connectionReleaseMode = getLogicalConnection().getConnectionHandlingMode().getReleaseMode();
|
||||
if ( connectionReleaseMode == ConnectionReleaseMode.AFTER_STATEMENT ||
|
||||
connectionReleaseMode == ConnectionReleaseMode.AFTER_TRANSACTION ||
|
||||
connectionReleaseMode == ConnectionReleaseMode.BEFORE_TRANSACTION_COMPLETION ) {
|
||||
this.logicalConnection.afterTransaction();
|
||||
switch ( getLogicalConnection().getConnectionHandlingMode().getReleaseMode() ) {
|
||||
case AFTER_STATEMENT:
|
||||
case AFTER_TRANSACTION:
|
||||
case BEFORE_TRANSACTION_COMPLETION:
|
||||
logicalConnection.afterTransaction();
|
||||
}
|
||||
}
|
||||
|
||||
private void releaseResources() {
|
||||
getLogicalConnection().getResourceRegistry().releaseResources();
|
||||
}
|
||||
|
||||
private boolean hasRegisteredResources() {
|
||||
return getLogicalConnection().getResourceRegistry().hasRegisteredResources();
|
||||
}
|
||||
|
||||
private ConnectionReleaseMode determineConnectionReleaseMode(
|
||||
JdbcConnectionAccess jdbcConnectionAccess,
|
||||
boolean isUserSuppliedConnection,
|
||||
ConnectionReleaseMode connectionReleaseMode) {
|
||||
if ( isUserSuppliedConnection ) {
|
||||
return ConnectionReleaseMode.ON_CLOSE;
|
||||
}
|
||||
else if ( connectionReleaseMode == ConnectionReleaseMode.AFTER_STATEMENT &&
|
||||
! jdbcConnectionAccess.supportsAggressiveRelease() ) {
|
||||
LOG.debug( "Connection provider reports to not support aggressive release; overriding" );
|
||||
return ConnectionReleaseMode.AFTER_TRANSACTION;
|
||||
}
|
||||
else {
|
||||
return connectionReleaseMode;
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public <T> T coordinateWork(WorkExecutorVisitable<T> work) {
|
||||
final Connection connection = getLogicalConnection().getPhysicalConnection();
|
||||
|
@ -325,7 +298,7 @@ public class JdbcCoordinatorImpl implements JdbcCoordinator {
|
|||
|
||||
@Override
|
||||
public boolean isReadyForSerialization() {
|
||||
return this.isUserSuppliedConnection
|
||||
return isUserSuppliedConnection
|
||||
? ! getLogicalConnection().isPhysicallyConnected()
|
||||
: ! hasRegisteredResources();
|
||||
}
|
||||
|
@ -349,19 +322,20 @@ public class JdbcCoordinatorImpl implements JdbcCoordinator {
|
|||
lastQuery.cancel();
|
||||
}
|
||||
}
|
||||
catch (SQLException sqle) {
|
||||
SqlExceptionHelper sqlExceptionHelper = jdbcServices.getSqlExceptionHelper();
|
||||
//Should always be non-null, but to make sure as the implementation is lazy:
|
||||
if ( sqlExceptionHelper == null ) {
|
||||
sqlExceptionHelper = new SqlExceptionHelper( false );
|
||||
}
|
||||
throw sqlExceptionHelper.convert( sqle, "Cannot cancel query" );
|
||||
catch ( SQLException sqle ) {
|
||||
throw safeSqlExceptionHelper().convert( sqle, "Cannot cancel query" );
|
||||
}
|
||||
finally {
|
||||
lastQuery = null;
|
||||
}
|
||||
}
|
||||
|
||||
private SqlExceptionHelper safeSqlExceptionHelper() {
|
||||
final SqlExceptionHelper sqlExceptionHelper = sqlExceptionHelper();
|
||||
//Should always be non-null, but to make sure as the implementation is lazy:
|
||||
return sqlExceptionHelper == null ? new SqlExceptionHelper( false ) : sqlExceptionHelper;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enableReleases() {
|
||||
releasesEnabled = true;
|
||||
|
@ -439,7 +413,7 @@ public class JdbcCoordinatorImpl implements JdbcCoordinator {
|
|||
|
||||
@Override
|
||||
public boolean isActive() {
|
||||
return !sessionFactory().isClosed();
|
||||
return owner.getJdbcSessionContext().isActive();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -449,8 +423,8 @@ public class JdbcCoordinatorImpl implements JdbcCoordinator {
|
|||
|
||||
@Override
|
||||
public void beforeTransactionCompletion() {
|
||||
this.owner.beforeTransactionCompletion();
|
||||
this.logicalConnection.beforeTransactionCompletion();
|
||||
owner.beforeTransactionCompletion();
|
||||
logicalConnection.beforeTransactionCompletion();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -461,7 +435,7 @@ public class JdbcCoordinatorImpl implements JdbcCoordinator {
|
|||
|
||||
@Override
|
||||
public JdbcSessionOwner getJdbcSessionOwner() {
|
||||
return this.owner;
|
||||
return owner;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -491,7 +465,7 @@ public class JdbcCoordinatorImpl implements JdbcCoordinator {
|
|||
* @param ois The stream into which to write our state
|
||||
* @param owner The Jdbc Session owner which owns the JdbcCoordinatorImpl to be deserialized.
|
||||
*
|
||||
* @return The deserialized JdbcCoordinatorImpl
|
||||
* @return The deserialized {@code JdbcCoordinatorImpl}
|
||||
*
|
||||
* @throws IOException Trouble accessing the stream
|
||||
* @throws ClassNotFoundException Trouble reading the stream
|
||||
|
@ -500,7 +474,7 @@ public class JdbcCoordinatorImpl implements JdbcCoordinator {
|
|||
ObjectInputStream ois,
|
||||
JdbcSessionOwner owner) throws IOException, ClassNotFoundException {
|
||||
final boolean isUserSuppliedConnection = ois.readBoolean();
|
||||
LogicalConnectionImplementor logicalConnection;
|
||||
final LogicalConnectionImplementor logicalConnection;
|
||||
if ( isUserSuppliedConnection ) {
|
||||
logicalConnection = LogicalConnectionProvidedImpl.deserialize( ois );
|
||||
}
|
||||
|
|
|
@ -11,11 +11,11 @@ import java.sql.PreparedStatement;
|
|||
import java.sql.SQLException;
|
||||
|
||||
import org.hibernate.AssertionFailure;
|
||||
import org.hibernate.boot.spi.SessionFactoryOptions;
|
||||
import org.hibernate.engine.jdbc.spi.JdbcServices;
|
||||
import org.hibernate.engine.jdbc.spi.MutationStatementPreparer;
|
||||
import org.hibernate.engine.jdbc.spi.SqlExceptionHelper;
|
||||
import org.hibernate.resource.jdbc.spi.JdbcObserver;
|
||||
import org.hibernate.resource.jdbc.spi.JdbcSessionContext;
|
||||
import org.hibernate.resource.jdbc.spi.LogicalConnectionImplementor;
|
||||
|
||||
/**
|
||||
|
@ -138,8 +138,7 @@ public class MutationStatementPreparerImpl implements MutationStatementPreparer
|
|||
return jdbcServices.getSqlExceptionHelper();
|
||||
}
|
||||
|
||||
protected final SessionFactoryOptions settings() {
|
||||
//noinspection resource
|
||||
return jdbcCoordinator.sessionFactory().getSessionFactoryOptions();
|
||||
protected final JdbcSessionContext settings() {
|
||||
return jdbcCoordinator.getJdbcSessionOwner().getJdbcSessionContext();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,11 +14,11 @@ import java.sql.Statement;
|
|||
|
||||
import org.hibernate.AssertionFailure;
|
||||
import org.hibernate.ScrollMode;
|
||||
import org.hibernate.boot.spi.SessionFactoryOptions;
|
||||
import org.hibernate.engine.jdbc.spi.JdbcServices;
|
||||
import org.hibernate.engine.jdbc.spi.SqlExceptionHelper;
|
||||
import org.hibernate.engine.jdbc.spi.StatementPreparer;
|
||||
import org.hibernate.resource.jdbc.spi.JdbcObserver;
|
||||
import org.hibernate.resource.jdbc.spi.JdbcSessionContext;
|
||||
import org.hibernate.resource.jdbc.spi.LogicalConnectionImplementor;
|
||||
|
||||
/**
|
||||
|
@ -42,8 +42,8 @@ class StatementPreparerImpl implements StatementPreparer {
|
|||
this.jdbcServices = jdbcServices;
|
||||
}
|
||||
|
||||
protected final SessionFactoryOptions settings() {
|
||||
return jdbcCoordinator.sessionFactory().getSessionFactoryOptions();
|
||||
protected final JdbcSessionContext settings() {
|
||||
return jdbcCoordinator.getJdbcSessionOwner().getJdbcSessionContext();
|
||||
}
|
||||
|
||||
protected final Connection connection() {
|
||||
|
@ -214,8 +214,8 @@ class StatementPreparerImpl implements StatementPreparer {
|
|||
}
|
||||
|
||||
private void setStatementFetchSize(PreparedStatement statement) throws SQLException {
|
||||
if ( settings().getJdbcFetchSize() != null ) {
|
||||
statement.setFetchSize( settings().getJdbcFetchSize() );
|
||||
if ( settings().getFetchSizeOrNull() != null ) {
|
||||
statement.setFetchSize( settings().getFetchSizeOrNull() );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -16,30 +16,31 @@ import org.hibernate.service.Service;
|
|||
import org.hibernate.sql.exec.internal.JdbcSelectExecutorStandardImpl;
|
||||
import org.hibernate.sql.exec.internal.StandardJdbcMutationExecutor;
|
||||
import org.hibernate.sql.exec.spi.JdbcMutationExecutor;
|
||||
import org.hibernate.sql.exec.spi.JdbcOperationQueryMutation;
|
||||
import org.hibernate.sql.exec.spi.JdbcOperationQuerySelect;
|
||||
import org.hibernate.sql.exec.spi.JdbcSelectExecutor;
|
||||
|
||||
/**
|
||||
* Contract for services around JDBC operations. These represent shared resources, aka not varied by session/use.
|
||||
* Provides access to services related to JDBC operations.
|
||||
* <p>
|
||||
* These services represent shared resources that do not vary by session.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface JdbcServices extends Service {
|
||||
/**
|
||||
* Obtain the JdbcEnvironment backing this JdbcServices instance.
|
||||
* Obtain the {@link JdbcEnvironment} backing this {@code JdbcServices} instance.
|
||||
*/
|
||||
JdbcEnvironment getJdbcEnvironment();
|
||||
|
||||
/**
|
||||
* Obtain a JdbcConnectionAccess usable from bootstrap actions
|
||||
* (hbm2ddl.auto, Dialect resolution, etc).
|
||||
* Obtain a {@link JdbcConnectionAccess} usable from bootstrap actions
|
||||
* (hbm2ddl.auto, {@code Dialect} resolution, etc).
|
||||
*/
|
||||
JdbcConnectionAccess getBootstrapJdbcConnectionAccess();
|
||||
|
||||
/**
|
||||
* Obtain the dialect of the database.
|
||||
*
|
||||
* @return The database dialect.
|
||||
*/
|
||||
Dialect getDialect();
|
||||
|
||||
|
@ -60,15 +61,19 @@ public interface JdbcServices extends Service {
|
|||
/**
|
||||
* Obtain information about supported behavior reported by the JDBC driver.
|
||||
* <p>
|
||||
* Yuck, yuck, yuck! Much prefer this to be part of a "basic settings" type object.
|
||||
* Yuck, yuck, yuck! Much prefer this to be part of a "basic settings" type object.
|
||||
*
|
||||
* @return The extracted database metadata, oddly enough :)
|
||||
*/
|
||||
ExtractedDatabaseMetaData getExtractedMetaDataSupport();
|
||||
|
||||
/**
|
||||
* Create an instance of a {@link LobCreator} appropriate for the current environment, mainly meant to account for
|
||||
* variance between JDBC 4 (<= JDK 1.6) and JDBC3 (>= JDK 1.5).
|
||||
* Create an instance of a {@link LobCreator} appropriate for the current environment,
|
||||
* mainly meant to account for variance between:
|
||||
* <ul>
|
||||
* <li>JDBC 4 (<= JDK 1.6) and
|
||||
* <li>JDBC 3 (>= JDK 1.5).
|
||||
* </ul>
|
||||
*
|
||||
* @param lobCreationContext The context in which the LOB is being created
|
||||
* @return The LOB creator.
|
||||
|
@ -76,12 +81,15 @@ public interface JdbcServices extends Service {
|
|||
LobCreator getLobCreator(LobCreationContext lobCreationContext);
|
||||
|
||||
/**
|
||||
* Access the executor for {@link JdbcOperationQuerySelect} operations
|
||||
* Access the executor for {@link JdbcOperationQuerySelect} operations.
|
||||
*/
|
||||
default JdbcSelectExecutor getJdbcSelectExecutor() {
|
||||
return JdbcSelectExecutorStandardImpl.INSTANCE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Access the executor for {@link JdbcOperationQueryMutation} operations.
|
||||
*/
|
||||
default JdbcMutationExecutor getJdbcMutationExecutor() {
|
||||
return StandardJdbcMutationExecutor.INSTANCE;
|
||||
}
|
||||
|
|
|
@ -226,7 +226,19 @@ public abstract class AbstractSharedSessionContract implements SharedSessionCont
|
|||
}
|
||||
|
||||
private JdbcSessionContextImpl createJdbcSessionContext(StatementInspector statementInspector) {
|
||||
return new JdbcSessionContextImpl(this, statementInspector, connectionHandlingMode, fastSessionServices );
|
||||
return new JdbcSessionContextImpl(
|
||||
factory,
|
||||
statementInspector,
|
||||
connectionHandlingMode,
|
||||
fastSessionServices.jdbcServices,
|
||||
fastSessionServices.batchBuilder,
|
||||
// TODO: this object is deprecated and should be removed
|
||||
new JdbcObserverImpl(
|
||||
fastSessionServices.getDefaultJdbcObserver(),
|
||||
sessionEventsManager,
|
||||
() -> jdbcCoordinator.abortBatch() // since jdbcCoordinator not yet initialized here
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
private String getTenantId( SessionFactoryImpl factory, SessionCreationOptions options ) {
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
*/
|
||||
package org.hibernate.internal;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
@ -24,6 +23,7 @@ import org.hibernate.engine.jdbc.batch.spi.BatchBuilder;
|
|||
import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider;
|
||||
import org.hibernate.engine.jdbc.connections.spi.MultiTenantConnectionProvider;
|
||||
import org.hibernate.engine.jdbc.spi.JdbcServices;
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.event.service.spi.EventListenerGroup;
|
||||
import org.hibernate.event.service.spi.EventListenerRegistry;
|
||||
import org.hibernate.event.spi.AutoFlushEventListener;
|
||||
|
@ -72,6 +72,7 @@ import jakarta.persistence.CacheRetrieveMode;
|
|||
import jakarta.persistence.CacheStoreMode;
|
||||
import jakarta.persistence.PessimisticLockScope;
|
||||
|
||||
import static java.util.Collections.unmodifiableMap;
|
||||
import static org.hibernate.cfg.AvailableSettings.JAKARTA_LOCK_SCOPE;
|
||||
import static org.hibernate.cfg.AvailableSettings.JAKARTA_LOCK_TIMEOUT;
|
||||
import static org.hibernate.cfg.AvailableSettings.JAKARTA_SHARED_CACHE_RETRIEVE_MODE;
|
||||
|
@ -83,19 +84,19 @@ import static org.hibernate.cfg.AvailableSettings.JPA_SHARED_CACHE_STORE_MODE;
|
|||
|
||||
/**
|
||||
* Internal component.
|
||||
*
|
||||
* <p>
|
||||
* Collects any components that any Session implementation will likely need
|
||||
* for faster access and reduced allocations.
|
||||
* Conceptually this acts as an immutable caching intermediary between Session
|
||||
* and SessionFactory.
|
||||
* Designed to be immutable, and shared across Session instances.
|
||||
*
|
||||
* Assumes to be created infrequently, possibly only once per SessionFactory.
|
||||
*
|
||||
* <p>
|
||||
* Designed to be immutable, shared across Session instances, and created infrequently,
|
||||
* possibly only once per SessionFactory.
|
||||
* <p>
|
||||
* If the Session is requiring to retrieve (or compute) anything from the SessionFactory,
|
||||
* and this computation would result in the same outcome for any Session created on
|
||||
* this same SessionFactory, then it belongs in a final field of this class.
|
||||
*
|
||||
* <p>
|
||||
* Finally, consider also limiting the size of each Session: some fields could be good
|
||||
* candidates to be replaced with access via this object.
|
||||
*
|
||||
|
@ -178,14 +179,14 @@ public final class FastSessionServices {
|
|||
private final FormatMapper jsonFormatMapper;
|
||||
private final FormatMapper xmlFormatMapper;
|
||||
|
||||
FastSessionServices(SessionFactoryImpl sf) {
|
||||
Objects.requireNonNull( sf );
|
||||
final ServiceRegistryImplementor sr = sf.getServiceRegistry();
|
||||
final JdbcServices jdbcServices = sf.getJdbcServices();
|
||||
final SessionFactoryOptions sessionFactoryOptions = sf.getSessionFactoryOptions();
|
||||
FastSessionServices(SessionFactoryImplementor sessionFactory) {
|
||||
Objects.requireNonNull( sessionFactory );
|
||||
final ServiceRegistryImplementor serviceRegistry = sessionFactory.getServiceRegistry();
|
||||
final JdbcServices jdbcServices = sessionFactory.getJdbcServices();
|
||||
final SessionFactoryOptions sessionFactoryOptions = sessionFactory.getSessionFactoryOptions();
|
||||
|
||||
// Pre-compute all iterators on Event listeners:
|
||||
final EventListenerRegistry eventListenerRegistry = sr.getService( EventListenerRegistry.class );
|
||||
final EventListenerRegistry eventListenerRegistry = serviceRegistry.getService( EventListenerRegistry.class );
|
||||
this.eventListenerGroup_AUTO_FLUSH = listeners( eventListenerRegistry, EventType.AUTO_FLUSH );
|
||||
this.eventListenerGroup_CLEAR = listeners( eventListenerRegistry, EventType.CLEAR );
|
||||
this.eventListenerGroup_DELETE = listeners( eventListenerRegistry, EventType.DELETE );
|
||||
|
@ -230,30 +231,34 @@ public final class FastSessionServices {
|
|||
this.preferredSqlTypeCodeForBoolean = sessionFactoryOptions.getPreferredSqlTypeCodeForBoolean();
|
||||
this.defaultTimeZoneStorageStrategy = sessionFactoryOptions.getDefaultTimeZoneStorageStrategy();
|
||||
this.defaultJdbcBatchSize = sessionFactoryOptions.getJdbcBatchSize();
|
||||
this.requiresMultiTenantConnectionProvider = sf.getSessionFactoryOptions().isMultiTenancyEnabled();
|
||||
this.requiresMultiTenantConnectionProvider = sessionFactory.getSessionFactoryOptions().isMultiTenancyEnabled();
|
||||
|
||||
//Some "hot" services:
|
||||
this.connectionProvider = requiresMultiTenantConnectionProvider ? null : sr.getService( ConnectionProvider.class );
|
||||
this.multiTenantConnectionProvider = requiresMultiTenantConnectionProvider ? sr.getService( MultiTenantConnectionProvider.class ) : null;
|
||||
this.classLoaderService = sr.getService( ClassLoaderService.class );
|
||||
this.transactionCoordinatorBuilder = sr.getService( TransactionCoordinatorBuilder.class );
|
||||
this.jdbcServices = sr.getService( JdbcServices.class );
|
||||
this.entityCopyObserverFactory = sr.getService( EntityCopyObserverFactory.class );
|
||||
this.connectionProvider = requiresMultiTenantConnectionProvider
|
||||
? null
|
||||
: serviceRegistry.getService( ConnectionProvider.class );
|
||||
this.multiTenantConnectionProvider = requiresMultiTenantConnectionProvider
|
||||
? serviceRegistry.getService( MultiTenantConnectionProvider.class )
|
||||
: null;
|
||||
this.classLoaderService = serviceRegistry.getService( ClassLoaderService.class );
|
||||
this.transactionCoordinatorBuilder = serviceRegistry.getService( TransactionCoordinatorBuilder.class );
|
||||
this.jdbcServices = serviceRegistry.getService( JdbcServices.class );
|
||||
this.entityCopyObserverFactory = serviceRegistry.getService( EntityCopyObserverFactory.class );
|
||||
|
||||
this.isJtaTransactionAccessible = isTransactionAccessible( sf, transactionCoordinatorBuilder );
|
||||
this.isJtaTransactionAccessible = isTransactionAccessible( sessionFactory, transactionCoordinatorBuilder );
|
||||
|
||||
this.defaultSessionProperties = initializeDefaultSessionProperties( sf );
|
||||
this.defaultSessionProperties = initializeDefaultSessionProperties( sessionFactory );
|
||||
this.defaultCacheStoreMode = determineCacheStoreMode( defaultSessionProperties );
|
||||
this.defaultCacheRetrieveMode = determineCacheRetrieveMode( defaultSessionProperties );
|
||||
this.initialSessionCacheMode = CacheModeHelper.interpretCacheMode( defaultCacheStoreMode, defaultCacheRetrieveMode );
|
||||
this.discardOnClose = sessionFactoryOptions.isReleaseResourcesOnCloseEnabled();
|
||||
this.defaultJdbcObservers = new ConnectionObserverStatsBridge( sf );
|
||||
this.defaultJdbcObservers = new ConnectionObserverStatsBridge( sessionFactory );
|
||||
this.defaultSessionEventListeners = sessionFactoryOptions.getBaselineSessionEventsListenerBuilder();
|
||||
this.defaultLockOptions = initializeDefaultLockOptions( defaultSessionProperties );
|
||||
this.initialSessionFlushMode = initializeDefaultFlushMode( defaultSessionProperties );
|
||||
this.jsonFormatMapper = sessionFactoryOptions.getJsonFormatMapper();
|
||||
this.xmlFormatMapper = sessionFactoryOptions.getXmlFormatMapper();
|
||||
this.batchBuilder = sr.getService( BatchBuilder.class );
|
||||
this.batchBuilder = serviceRegistry.getService( BatchBuilder.class );
|
||||
}
|
||||
|
||||
private static FlushMode initializeDefaultFlushMode(Map<String, Object> defaultSessionProperties) {
|
||||
|
@ -271,27 +276,29 @@ public final class FastSessionServices {
|
|||
return elr.getEventListenerGroup( type );
|
||||
}
|
||||
|
||||
private static boolean isTransactionAccessible(SessionFactoryImpl sf, TransactionCoordinatorBuilder transactionCoordinatorBuilder) {
|
||||
private static boolean isTransactionAccessible(
|
||||
SessionFactoryImplementor factory,
|
||||
TransactionCoordinatorBuilder transactionCoordinatorBuilder) {
|
||||
// JPA requires that access not be provided to the transaction when using JTA.
|
||||
// This is overridden when SessionFactoryOptions isJtaTransactionAccessEnabled() is true.
|
||||
return !( sf.getSessionFactoryOptions().getJpaCompliance().isJpaTransactionComplianceEnabled()
|
||||
&& transactionCoordinatorBuilder.isJta()
|
||||
&& !sf.getSessionFactoryOptions().isJtaTransactionAccessEnabled() );
|
||||
return !factory.getSessionFactoryOptions().getJpaCompliance().isJpaTransactionComplianceEnabled()
|
||||
|| !transactionCoordinatorBuilder.isJta()
|
||||
|| factory.getSessionFactoryOptions().isJtaTransactionAccessEnabled();
|
||||
}
|
||||
|
||||
private static Map<String, Object> initializeDefaultSessionProperties(SessionFactoryImpl sf) {
|
||||
HashMap<String,Object> p = new HashMap<>();
|
||||
private static Map<String, Object> initializeDefaultSessionProperties(SessionFactoryImplementor factory) {
|
||||
final HashMap<String,Object> settings = new HashMap<>();
|
||||
|
||||
//Static defaults:
|
||||
p.putIfAbsent( AvailableSettings.FLUSH_MODE, FlushMode.AUTO.name() );
|
||||
p.putIfAbsent( JPA_LOCK_SCOPE, PessimisticLockScope.EXTENDED.name() );
|
||||
p.putIfAbsent( JAKARTA_LOCK_SCOPE, PessimisticLockScope.EXTENDED.name() );
|
||||
p.putIfAbsent( JPA_LOCK_TIMEOUT, LockOptions.WAIT_FOREVER );
|
||||
p.putIfAbsent( JAKARTA_LOCK_TIMEOUT, LockOptions.WAIT_FOREVER );
|
||||
p.putIfAbsent( JPA_SHARED_CACHE_RETRIEVE_MODE, CacheModeHelper.DEFAULT_RETRIEVE_MODE );
|
||||
p.putIfAbsent( JAKARTA_SHARED_CACHE_RETRIEVE_MODE, CacheModeHelper.DEFAULT_RETRIEVE_MODE );
|
||||
p.putIfAbsent( JPA_SHARED_CACHE_STORE_MODE, CacheModeHelper.DEFAULT_STORE_MODE );
|
||||
p.putIfAbsent( JAKARTA_SHARED_CACHE_STORE_MODE, CacheModeHelper.DEFAULT_STORE_MODE );
|
||||
settings.putIfAbsent( AvailableSettings.FLUSH_MODE, FlushMode.AUTO.name() );
|
||||
settings.putIfAbsent( JPA_LOCK_SCOPE, PessimisticLockScope.EXTENDED.name() );
|
||||
settings.putIfAbsent( JAKARTA_LOCK_SCOPE, PessimisticLockScope.EXTENDED.name() );
|
||||
settings.putIfAbsent( JPA_LOCK_TIMEOUT, LockOptions.WAIT_FOREVER );
|
||||
settings.putIfAbsent( JAKARTA_LOCK_TIMEOUT, LockOptions.WAIT_FOREVER );
|
||||
settings.putIfAbsent( JPA_SHARED_CACHE_RETRIEVE_MODE, CacheModeHelper.DEFAULT_RETRIEVE_MODE );
|
||||
settings.putIfAbsent( JAKARTA_SHARED_CACHE_RETRIEVE_MODE, CacheModeHelper.DEFAULT_RETRIEVE_MODE );
|
||||
settings.putIfAbsent( JPA_SHARED_CACHE_STORE_MODE, CacheModeHelper.DEFAULT_STORE_MODE );
|
||||
settings.putIfAbsent( JAKARTA_SHARED_CACHE_STORE_MODE, CacheModeHelper.DEFAULT_STORE_MODE );
|
||||
|
||||
//Defaults defined by SessionFactory configuration:
|
||||
final String[] ENTITY_MANAGER_SPECIFIC_PROPERTIES = {
|
||||
|
@ -309,41 +316,31 @@ public final class FastSessionServices {
|
|||
LegacySpecHints.HINT_JAVAEE_CACHE_STORE_MODE,
|
||||
LegacySpecHints.HINT_JAVAEE_QUERY_TIMEOUT
|
||||
};
|
||||
final Map<String, Object> properties = sf.getProperties();
|
||||
final Map<String, Object> properties = factory.getProperties();
|
||||
for ( String key : ENTITY_MANAGER_SPECIFIC_PROPERTIES ) {
|
||||
if ( properties.containsKey( key ) ) {
|
||||
p.put( key, properties.get( key ) );
|
||||
settings.put( key, properties.get( key ) );
|
||||
}
|
||||
}
|
||||
return Collections.unmodifiableMap( p );
|
||||
return unmodifiableMap( settings );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param properties the Session properties
|
||||
* @return either the CacheStoreMode as defined in the Session specific properties, or as defined in the
|
||||
* properties shared across all sessions (the defaults).
|
||||
* @return either the CacheStoreMode as defined in the Session specific properties,
|
||||
* or as defined in the properties shared across all sessions (the defaults).
|
||||
*/
|
||||
CacheStoreMode getCacheStoreMode(final Map<String, Object> properties) {
|
||||
if ( properties == null ) {
|
||||
return this.defaultCacheStoreMode;
|
||||
}
|
||||
else {
|
||||
return determineCacheStoreMode( properties );
|
||||
}
|
||||
return properties == null ? defaultCacheStoreMode : determineCacheStoreMode( properties );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param properties the Session properties
|
||||
* @return either the CacheRetrieveMode as defined in the Session specific properties, or as defined in the
|
||||
* properties shared across all sessions (the defaults).
|
||||
* @return either the CacheRetrieveMode as defined in the Session specific properties,
|
||||
* or as defined in the properties shared across all sessions (the defaults).
|
||||
*/
|
||||
CacheRetrieveMode getCacheRetrieveMode(Map<String, Object> properties) {
|
||||
if ( properties == null ) {
|
||||
return this.defaultCacheRetrieveMode;
|
||||
}
|
||||
else {
|
||||
return determineCacheRetrieveMode( properties );
|
||||
}
|
||||
return properties == null ? defaultCacheRetrieveMode : determineCacheRetrieveMode( properties );
|
||||
}
|
||||
|
||||
private static CacheRetrieveMode determineCacheRetrieveMode(Map<String, Object> settings) {
|
||||
|
|
|
@ -9,22 +9,27 @@ package org.hibernate.internal;
|
|||
import java.sql.Connection;
|
||||
|
||||
import org.hibernate.engine.spi.SessionEventListenerManager;
|
||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||
import org.hibernate.resource.jdbc.spi.JdbcObserver;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*
|
||||
* @deprecated since {@link JdbcObserver} is deprecated
|
||||
*/
|
||||
@Deprecated(since = "5.4", forRemoval = true)
|
||||
public final class JdbcObserverImpl implements JdbcObserver {
|
||||
|
||||
private final ConnectionObserverStatsBridge observer;
|
||||
private final SessionEventListenerManager eventListenerManager;
|
||||
private final SharedSessionContractImplementor session;
|
||||
private final Runnable abortBatch;
|
||||
|
||||
public JdbcObserverImpl(SharedSessionContractImplementor session, FastSessionServices fastSessionServices) {
|
||||
this.session = session;
|
||||
this.observer = fastSessionServices.getDefaultJdbcObserver();
|
||||
this.eventListenerManager = session.getEventListenerManager();
|
||||
public JdbcObserverImpl(
|
||||
ConnectionObserverStatsBridge observer,
|
||||
SessionEventListenerManager eventListenerManager,
|
||||
Runnable abortBatch) {
|
||||
this.observer = observer;
|
||||
this.eventListenerManager = eventListenerManager;
|
||||
this.abortBatch = abortBatch;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -78,7 +83,7 @@ public final class JdbcObserverImpl implements JdbcObserver {
|
|||
|
||||
@Override
|
||||
public void jdbcReleaseRegistryResourcesStart() {
|
||||
session.getJdbcCoordinator().abortBatch();
|
||||
abortBatch.run();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -7,8 +7,10 @@
|
|||
package org.hibernate.internal;
|
||||
|
||||
import org.hibernate.boot.spi.SessionFactoryOptions;
|
||||
import org.hibernate.engine.jdbc.batch.spi.BatchBuilder;
|
||||
import org.hibernate.engine.jdbc.spi.JdbcServices;
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||
import org.hibernate.jpa.spi.JpaCompliance;
|
||||
import org.hibernate.resource.jdbc.spi.JdbcObserver;
|
||||
import org.hibernate.resource.jdbc.spi.JdbcSessionContext;
|
||||
import org.hibernate.resource.jdbc.spi.PhysicalConnectionHandlingMode;
|
||||
|
@ -22,22 +24,26 @@ public class JdbcSessionContextImpl implements JdbcSessionContext {
|
|||
private final SessionFactoryImplementor sessionFactory;
|
||||
private final StatementInspector statementInspector;
|
||||
private final PhysicalConnectionHandlingMode connectionHandlingMode;
|
||||
private final JdbcServices jdbcServices;
|
||||
private final BatchBuilder batchBuilder;
|
||||
|
||||
private final transient ServiceRegistry serviceRegistry;
|
||||
private final transient JdbcObserver jdbcObserver;
|
||||
|
||||
public JdbcSessionContextImpl(
|
||||
SharedSessionContractImplementor session,
|
||||
SessionFactoryImplementor sessionFactory,
|
||||
StatementInspector statementInspector,
|
||||
PhysicalConnectionHandlingMode connectionHandlingMode,
|
||||
FastSessionServices fastSessionServices) {
|
||||
this.sessionFactory = session.getFactory();
|
||||
JdbcServices jdbcServices,
|
||||
BatchBuilder batchBuilder,
|
||||
JdbcObserver jdbcObserver) {
|
||||
this.sessionFactory = sessionFactory;
|
||||
this.statementInspector = statementInspector;
|
||||
this.connectionHandlingMode = connectionHandlingMode;
|
||||
this.serviceRegistry = sessionFactory.getServiceRegistry();
|
||||
this.jdbcObserver = new JdbcObserverImpl( session, fastSessionServices );
|
||||
this.jdbcServices = jdbcServices;
|
||||
this.batchBuilder = batchBuilder;
|
||||
this.jdbcObserver = jdbcObserver;
|
||||
|
||||
if ( this.statementInspector == null ) {
|
||||
if ( statementInspector == null ) {
|
||||
throw new IllegalArgumentException( "StatementInspector cannot be null" );
|
||||
}
|
||||
}
|
||||
|
@ -52,11 +58,31 @@ public class JdbcSessionContextImpl implements JdbcSessionContext {
|
|||
return settings().isGetGeneratedKeysEnabled();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Override @Deprecated
|
||||
public int getFetchSize() {
|
||||
return settings().getJdbcFetchSize();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getFetchSizeOrNull() {
|
||||
return settings().getJdbcFetchSize();
|
||||
}
|
||||
|
||||
@Override
|
||||
public JpaCompliance getJpaCompliance() {
|
||||
return settings().getJpaCompliance();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPreferUserTransaction() {
|
||||
return settings().isPreferUserTransaction();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isJtaTrackByThread() {
|
||||
return settings().isJtaTrackByThread();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PhysicalConnectionHandlingMode getPhysicalConnectionHandlingMode() {
|
||||
return connectionHandlingMode;
|
||||
|
@ -72,22 +98,37 @@ public class JdbcSessionContextImpl implements JdbcSessionContext {
|
|||
return statementInspector;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Override @Deprecated
|
||||
public JdbcObserver getObserver() {
|
||||
return this.jdbcObserver;
|
||||
return jdbcObserver;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Override @Deprecated
|
||||
public SessionFactoryImplementor getSessionFactory() {
|
||||
return this.sessionFactory;
|
||||
return sessionFactory;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Override @Deprecated
|
||||
public ServiceRegistry getServiceRegistry() {
|
||||
return this.serviceRegistry;
|
||||
return sessionFactory.getServiceRegistry();
|
||||
}
|
||||
|
||||
private SessionFactoryOptions settings() {
|
||||
return this.sessionFactory.getSessionFactoryOptions();
|
||||
return sessionFactory.getSessionFactoryOptions();
|
||||
}
|
||||
|
||||
@Override
|
||||
public JdbcServices getJdbcServices() {
|
||||
return jdbcServices;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BatchBuilder getBatchBuilder() {
|
||||
return batchBuilder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isActive() {
|
||||
return !sessionFactory.isClosed();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,29 +22,32 @@ public interface LogicalConnection {
|
|||
* <p>
|
||||
* That is, has {@link #close} not yet been called?
|
||||
*
|
||||
* @return {@code true} if still open ({@link #close} has not been called yet); {@code false} if not open
|
||||
* ({@link #close} has been called).
|
||||
* @return {@code true} if still open, since {@link #close} has not yet been called;
|
||||
* {@code false} if not open, since {@link #close} was called.
|
||||
*/
|
||||
boolean isOpen();
|
||||
|
||||
/**
|
||||
* Closes the JdbcSession, making it inactive and forcing release of any held resources.
|
||||
* Closes the logical connection, making it inactive and forcing release of any held resources.
|
||||
*
|
||||
* @return Legacy :( Returns the JDBC {@code Connection} if the user passed in a {@code Connection} originally.
|
||||
* @return the JDBC {@code Connection} if the user passed in a {@code Connection} originally
|
||||
*
|
||||
* @apiNote The return type accommodates legacy functionality for user-supplied connections.
|
||||
*/
|
||||
Connection close();
|
||||
|
||||
/**
|
||||
* Is this JdbcSession currently physically connected?
|
||||
* Is this logical connection currently physically connected?
|
||||
* <p>
|
||||
* That is, does it currently hold a physical JDBC {@code Connection}?
|
||||
* That is, does it currently hold a physical JDBC {@link Connection}?
|
||||
*
|
||||
* @return {@code true} if the JdbcSession currently hold a JDBC {@code Connection}; {@code false} if it does not.
|
||||
* @return {@code true} if currently holding a JDBC {@code Connection};
|
||||
* {@code false} if not.
|
||||
*/
|
||||
boolean isPhysicallyConnected();
|
||||
|
||||
/**
|
||||
* Provides access to the registry of JDBC resources associated with this {@code LogicalConnection}.
|
||||
* Provides access to the registry of JDBC resources associated with this logical connection.
|
||||
*
|
||||
* @return The JDBC resource registry.
|
||||
*
|
||||
|
|
|
@ -12,8 +12,6 @@ import java.io.ObjectOutputStream;
|
|||
import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
|
||||
import org.hibernate.ConnectionAcquisitionMode;
|
||||
import org.hibernate.ConnectionReleaseMode;
|
||||
import org.hibernate.ResourceClosedException;
|
||||
import org.hibernate.engine.jdbc.connections.spi.JdbcConnectionAccess;
|
||||
import org.hibernate.engine.jdbc.spi.JdbcServices;
|
||||
|
@ -25,9 +23,15 @@ import org.hibernate.resource.jdbc.spi.PhysicalConnectionHandlingMode;
|
|||
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
import static org.hibernate.ConnectionAcquisitionMode.IMMEDIATELY;
|
||||
import static org.hibernate.ConnectionReleaseMode.AFTER_STATEMENT;
|
||||
import static org.hibernate.ConnectionReleaseMode.BEFORE_TRANSACTION_COMPLETION;
|
||||
import static org.hibernate.ConnectionReleaseMode.ON_CLOSE;
|
||||
import static org.hibernate.resource.jdbc.spi.PhysicalConnectionHandlingMode.DELAYED_ACQUISITION_AND_RELEASE_AFTER_TRANSACTION;
|
||||
|
||||
/**
|
||||
* Represents a LogicalConnection where we manage obtaining and releasing the Connection as needed.
|
||||
* This implementation does not claim to be threadsafe and is not designed to be used by multiple
|
||||
* This implementation does not claim to be thread-safe and is not designed to be used by multiple
|
||||
* threads, yet we do apply a limited amount of care to be able to void obscure exceptions when
|
||||
* this class is used in the wrong way.
|
||||
*
|
||||
|
@ -45,7 +49,7 @@ public class LogicalConnectionManagedImpl extends AbstractLogicalConnectionImple
|
|||
private transient Connection physicalConnection;
|
||||
private boolean closed;
|
||||
|
||||
private boolean providerDisablesAutoCommit;
|
||||
private final boolean providerDisablesAutoCommit;
|
||||
|
||||
public LogicalConnectionManagedImpl(
|
||||
JdbcConnectionAccess jdbcConnectionAccess,
|
||||
|
@ -62,7 +66,7 @@ public class LogicalConnectionManagedImpl extends AbstractLogicalConnectionImple
|
|||
|
||||
this.sqlExceptionHelper = jdbcServices.getSqlExceptionHelper();
|
||||
|
||||
if ( connectionHandlingMode.getAcquisitionMode() == ConnectionAcquisitionMode.IMMEDIATELY ) {
|
||||
if ( connectionHandlingMode.getAcquisitionMode() == IMMEDIATELY ) {
|
||||
acquireConnectionIfNeeded();
|
||||
}
|
||||
|
||||
|
@ -81,9 +85,9 @@ public class LogicalConnectionManagedImpl extends AbstractLogicalConnectionImple
|
|||
private PhysicalConnectionHandlingMode determineConnectionHandlingMode(
|
||||
PhysicalConnectionHandlingMode connectionHandlingMode,
|
||||
JdbcConnectionAccess jdbcConnectionAccess) {
|
||||
if ( connectionHandlingMode.getReleaseMode() == ConnectionReleaseMode.AFTER_STATEMENT
|
||||
if ( connectionHandlingMode.getReleaseMode() == AFTER_STATEMENT
|
||||
&& !jdbcConnectionAccess.supportsAggressiveRelease() ) {
|
||||
return PhysicalConnectionHandlingMode.DELAYED_ACQUISITION_AND_RELEASE_AFTER_TRANSACTION;
|
||||
return DELAYED_ACQUISITION_AND_RELEASE_AFTER_TRANSACTION;
|
||||
}
|
||||
|
||||
return connectionHandlingMode;
|
||||
|
@ -93,8 +97,11 @@ public class LogicalConnectionManagedImpl extends AbstractLogicalConnectionImple
|
|||
JdbcConnectionAccess jdbcConnectionAccess,
|
||||
JdbcSessionContext jdbcSessionContext,
|
||||
boolean closed) {
|
||||
this( jdbcConnectionAccess, jdbcSessionContext, new ResourceRegistryStandardImpl(),
|
||||
jdbcSessionContext.getSessionFactory().getFastSessionServices().jdbcServices
|
||||
this(
|
||||
jdbcConnectionAccess,
|
||||
jdbcSessionContext,
|
||||
new ResourceRegistryStandardImpl(),
|
||||
jdbcSessionContext.getJdbcServices()
|
||||
);
|
||||
this.closed = closed;
|
||||
}
|
||||
|
@ -105,7 +112,7 @@ public class LogicalConnectionManagedImpl extends AbstractLogicalConnectionImple
|
|||
try {
|
||||
physicalConnection = jdbcConnectionAccess.obtainConnection();
|
||||
}
|
||||
catch (SQLException e) {
|
||||
catch ( SQLException e ) {
|
||||
throw sqlExceptionHelper.convert( e, "Unable to acquire JDBC Connection" );
|
||||
}
|
||||
finally {
|
||||
|
@ -140,7 +147,7 @@ public class LogicalConnectionManagedImpl extends AbstractLogicalConnectionImple
|
|||
public void afterStatement() {
|
||||
super.afterStatement();
|
||||
|
||||
if ( connectionHandlingMode.getReleaseMode() == ConnectionReleaseMode.AFTER_STATEMENT ) {
|
||||
if ( connectionHandlingMode.getReleaseMode() == AFTER_STATEMENT ) {
|
||||
if ( getResourceRegistry().hasRegisteredResources() ) {
|
||||
log.debug( "Skipping aggressive release of JDBC Connection after-statement due to held resources" );
|
||||
}
|
||||
|
@ -154,7 +161,7 @@ public class LogicalConnectionManagedImpl extends AbstractLogicalConnectionImple
|
|||
@Override
|
||||
public void beforeTransactionCompletion() {
|
||||
super.beforeTransactionCompletion();
|
||||
if ( connectionHandlingMode.getReleaseMode() == ConnectionReleaseMode.BEFORE_TRANSACTION_COMPLETION ) {
|
||||
if ( connectionHandlingMode.getReleaseMode() == BEFORE_TRANSACTION_COMPLETION ) {
|
||||
log.debug( "Initiating JDBC connection release from beforeTransactionCompletion" );
|
||||
releaseConnection();
|
||||
}
|
||||
|
@ -164,7 +171,7 @@ public class LogicalConnectionManagedImpl extends AbstractLogicalConnectionImple
|
|||
public void afterTransaction() {
|
||||
super.afterTransaction();
|
||||
|
||||
if ( connectionHandlingMode.getReleaseMode() != ConnectionReleaseMode.ON_CLOSE ) {
|
||||
if ( connectionHandlingMode.getReleaseMode() != ON_CLOSE ) {
|
||||
// NOTE : we check for !ON_CLOSE here (rather than AFTER_TRANSACTION) to also catch:
|
||||
// - AFTER_STATEMENT cases that were circumvented due to held resources
|
||||
// - BEFORE_TRANSACTION_COMPLETION cases that were circumvented because a rollback occurred
|
||||
|
@ -270,8 +277,8 @@ public class LogicalConnectionManagedImpl extends AbstractLogicalConnectionImple
|
|||
|
||||
@Override
|
||||
public void begin() {
|
||||
initiallyAutoCommit = !doConnectionsFromProviderHaveAutoCommitDisabled() && determineInitialAutoCommitMode(
|
||||
getConnectionForTransactionManagement() );
|
||||
initiallyAutoCommit = !doConnectionsFromProviderHaveAutoCommitDisabled()
|
||||
&& determineInitialAutoCommitMode( getConnectionForTransactionManagement() );
|
||||
super.begin();
|
||||
}
|
||||
|
||||
|
|
|
@ -9,11 +9,12 @@ package org.hibernate.resource.jdbc.spi;
|
|||
import java.sql.Connection;
|
||||
|
||||
/**
|
||||
* @deprecated It is no longer possible to plug custom implementations of
|
||||
* this SPI. It will be removed.
|
||||
* @deprecated It is no longer possible to plug custom implementations
|
||||
* of this SPI. It will be removed.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
@Deprecated
|
||||
@Deprecated(since = "5.4", forRemoval = true)
|
||||
public interface JdbcObserver {
|
||||
void jdbcConnectionAcquisitionStart();
|
||||
void jdbcConnectionAcquisitionEnd(Connection connection);
|
||||
|
|
|
@ -6,33 +6,91 @@
|
|||
*/
|
||||
package org.hibernate.resource.jdbc.spi;
|
||||
|
||||
import org.hibernate.engine.jdbc.batch.spi.BatchBuilder;
|
||||
import org.hibernate.engine.jdbc.spi.JdbcServices;
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.jpa.spi.JpaCompliance;
|
||||
import org.hibernate.service.ServiceRegistry;
|
||||
|
||||
/**
|
||||
* Provides the {@code JdbcSession} with contextual information it needs during its lifecycle.
|
||||
* Provides the "JDBC session" with contextual information it needs during its lifecycle.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface JdbcSessionContext {
|
||||
/**
|
||||
* @see org.hibernate.cfg.AvailableSettings#USE_SCROLLABLE_RESULTSET
|
||||
*/
|
||||
boolean isScrollableResultSetsEnabled();
|
||||
|
||||
/**
|
||||
* @see org.hibernate.cfg.AvailableSettings#USE_GET_GENERATED_KEYS
|
||||
*/
|
||||
boolean isGetGeneratedKeysEnabled();
|
||||
|
||||
/**
|
||||
* @see org.hibernate.cfg.AvailableSettings#STATEMENT_FETCH_SIZE
|
||||
*/
|
||||
Integer getFetchSizeOrNull();
|
||||
|
||||
/**
|
||||
* @deprecated this is never called, and luckily so, because it's not null-safe
|
||||
*/
|
||||
@Deprecated(since = "6.2", forRemoval = true)
|
||||
int getFetchSize();
|
||||
|
||||
/**
|
||||
* @see org.hibernate.cfg.AvailableSettings#CONNECTION_PROVIDER_DISABLES_AUTOCOMMIT
|
||||
*/
|
||||
boolean doesConnectionProviderDisableAutoCommit();
|
||||
|
||||
/**
|
||||
* @see org.hibernate.cfg.AvailableSettings#PREFER_USER_TRANSACTION
|
||||
*/
|
||||
boolean isPreferUserTransaction();
|
||||
|
||||
/**
|
||||
* @see org.hibernate.cfg.AvailableSettings#JTA_TRACK_BY_THREAD
|
||||
*/
|
||||
boolean isJtaTrackByThread();
|
||||
|
||||
PhysicalConnectionHandlingMode getPhysicalConnectionHandlingMode();
|
||||
|
||||
boolean doesConnectionProviderDisableAutoCommit();
|
||||
|
||||
StatementInspector getStatementInspector();
|
||||
|
||||
JpaCompliance getJpaCompliance();
|
||||
|
||||
/**
|
||||
* @deprecated since {@link JdbcObserver} is deprecated
|
||||
*/
|
||||
@Deprecated(forRemoval = true)
|
||||
JdbcObserver getObserver();
|
||||
|
||||
/**
|
||||
* Retrieve the session factory for this environment.
|
||||
*
|
||||
* @return The session factory
|
||||
*
|
||||
* @deprecated exposing this here seems to kinda defeat the purpose of this SPI
|
||||
*/
|
||||
@Deprecated(since = "6.2")
|
||||
SessionFactoryImplementor getSessionFactory();
|
||||
|
||||
/**
|
||||
* Retrieve the service registry.
|
||||
*
|
||||
* @deprecated this is no longer called, and unnecessary, since the needed
|
||||
* services are now available via {@link #getJdbcServices()}
|
||||
*/
|
||||
@Deprecated(since = "6.2")
|
||||
ServiceRegistry getServiceRegistry();
|
||||
|
||||
JdbcServices getJdbcServices();
|
||||
|
||||
BatchBuilder getBatchBuilder();
|
||||
|
||||
/**
|
||||
* @see org.hibernate.resource.transaction.spi.TransactionCoordinatorOwner#isActive()
|
||||
*
|
||||
* @return {@code false} if the session factory was already destroyed
|
||||
*/
|
||||
boolean isActive();
|
||||
}
|
||||
|
|
|
@ -13,11 +13,13 @@ import java.util.concurrent.Callable;
|
|||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.engine.jdbc.connections.spi.JdbcConnectionAccess;
|
||||
import org.hibernate.engine.jdbc.spi.SqlExceptionHelper;
|
||||
import org.hibernate.resource.jdbc.spi.JdbcSessionOwner;
|
||||
import org.hibernate.resource.transaction.spi.IsolationDelegate;
|
||||
import org.hibernate.internal.CoreLogging;
|
||||
import org.hibernate.internal.CoreMessageLogger;
|
||||
import org.hibernate.jdbc.WorkExecutor;
|
||||
import org.hibernate.jdbc.WorkExecutorVisitable;
|
||||
import org.hibernate.resource.transaction.spi.TransactionCoordinatorOwner;
|
||||
|
||||
/**
|
||||
* @author Andrea Boriero
|
||||
|
@ -28,6 +30,17 @@ public class JdbcIsolationDelegate implements IsolationDelegate {
|
|||
private final JdbcConnectionAccess connectionAccess;
|
||||
private final SqlExceptionHelper sqlExceptionHelper;
|
||||
|
||||
public JdbcIsolationDelegate(TransactionCoordinatorOwner transactionCoordinatorOwner) {
|
||||
this( transactionCoordinatorOwner.getJdbcSessionOwner() );
|
||||
}
|
||||
|
||||
public JdbcIsolationDelegate(JdbcSessionOwner jdbcSessionOwner) {
|
||||
this(
|
||||
jdbcSessionOwner.getJdbcConnectionAccess(),
|
||||
jdbcSessionOwner.getJdbcSessionContext().getJdbcServices().getSqlExceptionHelper()
|
||||
);
|
||||
}
|
||||
|
||||
public JdbcIsolationDelegate(JdbcConnectionAccess connectionAccess, SqlExceptionHelper sqlExceptionHelper) {
|
||||
this.connectionAccess = connectionAccess;
|
||||
this.sqlExceptionHelper = sqlExceptionHelper;
|
||||
|
@ -45,7 +58,7 @@ public class JdbcIsolationDelegate implements IsolationDelegate {
|
|||
public <T> T delegateWork(WorkExecutorVisitable<T> work, boolean transacted) throws HibernateException {
|
||||
boolean wasAutoCommit = false;
|
||||
try {
|
||||
Connection connection = jdbcConnectionAccess().obtainConnection();
|
||||
final Connection connection = jdbcConnectionAccess().obtainConnection();
|
||||
try {
|
||||
if ( transacted ) {
|
||||
if ( connection.getAutoCommit() ) {
|
||||
|
@ -62,14 +75,14 @@ public class JdbcIsolationDelegate implements IsolationDelegate {
|
|||
|
||||
return result;
|
||||
}
|
||||
catch (Exception e) {
|
||||
catch ( Exception e ) {
|
||||
try {
|
||||
if ( transacted && !connection.isClosed() ) {
|
||||
connection.rollback();
|
||||
}
|
||||
}
|
||||
catch (Exception ignore) {
|
||||
LOG.unableToRollbackConnection( ignore );
|
||||
catch ( Exception exception ) {
|
||||
LOG.unableToRollbackConnection( exception );
|
||||
}
|
||||
|
||||
if ( e instanceof HibernateException ) {
|
||||
|
@ -87,19 +100,19 @@ public class JdbcIsolationDelegate implements IsolationDelegate {
|
|||
try {
|
||||
connection.setAutoCommit( true );
|
||||
}
|
||||
catch (Exception ignore) {
|
||||
catch ( Exception ignore ) {
|
||||
LOG.trace( "was unable to reset connection back to auto-commit" );
|
||||
}
|
||||
}
|
||||
try {
|
||||
jdbcConnectionAccess().releaseConnection( connection );
|
||||
}
|
||||
catch (Exception ignore) {
|
||||
catch ( Exception ignore ) {
|
||||
LOG.unableToReleaseIsolatedConnection( ignore );
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (SQLException sqle) {
|
||||
catch ( SQLException sqle ) {
|
||||
throw sqlExceptionHelper().convert( sqle, "unable to obtain isolated JDBC connection" );
|
||||
}
|
||||
}
|
||||
|
@ -110,11 +123,11 @@ public class JdbcIsolationDelegate implements IsolationDelegate {
|
|||
try {
|
||||
return callable.call();
|
||||
}
|
||||
catch (HibernateException e) {
|
||||
catch ( HibernateException e ) {
|
||||
throw e;
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new HibernateException(e);
|
||||
catch ( Exception e ) {
|
||||
throw new HibernateException( e );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,6 +15,8 @@ import org.hibernate.resource.transaction.spi.TransactionCoordinatorBuilder;
|
|||
import org.hibernate.resource.transaction.spi.TransactionCoordinatorOwner;
|
||||
import org.hibernate.tool.schema.internal.exec.JdbcContext;
|
||||
|
||||
import static org.hibernate.resource.jdbc.spi.PhysicalConnectionHandlingMode.DELAYED_ACQUISITION_AND_RELEASE_AFTER_TRANSACTION;
|
||||
|
||||
/**
|
||||
* Concrete builder for resource-local {@link TransactionCoordinator} instances.
|
||||
*
|
||||
|
@ -50,7 +52,7 @@ public class JdbcResourceLocalTransactionCoordinatorBuilderImpl implements Trans
|
|||
|
||||
@Override
|
||||
public PhysicalConnectionHandlingMode getDefaultConnectionHandlingMode() {
|
||||
return PhysicalConnectionHandlingMode.DELAYED_ACQUISITION_AND_RELEASE_AFTER_TRANSACTION;
|
||||
return DELAYED_ACQUISITION_AND_RELEASE_AFTER_TRANSACTION;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
package org.hibernate.resource.transaction.backend.jdbc.internal;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import jakarta.persistence.RollbackException;
|
||||
|
@ -16,7 +15,6 @@ import jakarta.transaction.Status;
|
|||
import org.hibernate.resource.transaction.spi.IsolationDelegate;
|
||||
import org.hibernate.internal.CoreMessageLogger;
|
||||
import org.hibernate.jpa.spi.JpaCompliance;
|
||||
import org.hibernate.resource.jdbc.spi.JdbcSessionOwner;
|
||||
import org.hibernate.resource.transaction.backend.jdbc.spi.JdbcResourceTransaction;
|
||||
import org.hibernate.resource.transaction.backend.jdbc.spi.JdbcResourceTransactionAccess;
|
||||
import org.hibernate.resource.transaction.internal.SynchronizationRegistryStandardImpl;
|
||||
|
@ -27,6 +25,7 @@ import org.hibernate.resource.transaction.spi.TransactionCoordinatorOwner;
|
|||
import org.hibernate.resource.transaction.spi.TransactionObserver;
|
||||
import org.hibernate.resource.transaction.spi.TransactionStatus;
|
||||
|
||||
import static java.util.Collections.emptyList;
|
||||
import static org.hibernate.internal.CoreLogging.messageLogger;
|
||||
|
||||
/**
|
||||
|
@ -66,12 +65,7 @@ public class JdbcResourceLocalTransactionCoordinatorImpl implements TransactionC
|
|||
this.transactionCoordinatorBuilder = transactionCoordinatorBuilder;
|
||||
this.jdbcResourceTransactionAccess = jdbcResourceTransactionAccess;
|
||||
this.transactionCoordinatorOwner = owner;
|
||||
|
||||
this.jpaCompliance = owner.getJdbcSessionOwner()
|
||||
.getJdbcSessionContext()
|
||||
.getSessionFactory()
|
||||
.getSessionFactoryOptions()
|
||||
.getJpaCompliance();
|
||||
this.jpaCompliance = owner.getJdbcSessionOwner().getJdbcSessionContext().getJpaCompliance();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -81,12 +75,7 @@ public class JdbcResourceLocalTransactionCoordinatorImpl implements TransactionC
|
|||
* @return TransactionObserver
|
||||
*/
|
||||
private Iterable<TransactionObserver> observers() {
|
||||
if ( observers == null || observers.isEmpty() ) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
else {
|
||||
return new ArrayList<>( observers );
|
||||
}
|
||||
return observers == null || observers.isEmpty() ? emptyList() : new ArrayList<>( observers );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -95,7 +84,8 @@ public class JdbcResourceLocalTransactionCoordinatorImpl implements TransactionC
|
|||
// coordinator. We lazily build it as we invalidate each delegate after each transaction (a delegate is
|
||||
// valid for just one transaction)
|
||||
if ( physicalTransactionDelegate == null ) {
|
||||
physicalTransactionDelegate = new TransactionDriverControlImpl( jdbcResourceTransactionAccess.getResourceLocalTransaction() );
|
||||
physicalTransactionDelegate =
|
||||
new TransactionDriverControlImpl( jdbcResourceTransactionAccess.getResourceLocalTransaction() );
|
||||
}
|
||||
return physicalTransactionDelegate;
|
||||
}
|
||||
|
@ -108,7 +98,8 @@ public class JdbcResourceLocalTransactionCoordinatorImpl implements TransactionC
|
|||
|
||||
@Override
|
||||
public boolean isJoined() {
|
||||
return physicalTransactionDelegate != null && getTransactionDriverControl().isActive( true );
|
||||
return physicalTransactionDelegate != null
|
||||
&& getTransactionDriverControl().isActive( true );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -133,17 +124,12 @@ public class JdbcResourceLocalTransactionCoordinatorImpl implements TransactionC
|
|||
|
||||
@Override
|
||||
public IsolationDelegate createIsolationDelegate() {
|
||||
final JdbcSessionOwner jdbcSessionOwner = transactionCoordinatorOwner.getJdbcSessionOwner();
|
||||
|
||||
return new JdbcIsolationDelegate(
|
||||
jdbcSessionOwner.getJdbcConnectionAccess(),
|
||||
jdbcSessionOwner.getJdbcSessionContext().getSessionFactory().getFastSessionServices().jdbcServices.getSqlExceptionHelper()
|
||||
);
|
||||
return new JdbcIsolationDelegate( transactionCoordinatorOwner );
|
||||
}
|
||||
|
||||
@Override
|
||||
public TransactionCoordinatorBuilder getTransactionCoordinatorBuilder() {
|
||||
return this.transactionCoordinatorBuilder;
|
||||
return transactionCoordinatorBuilder;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -153,14 +139,14 @@ public class JdbcResourceLocalTransactionCoordinatorImpl implements TransactionC
|
|||
|
||||
@Override
|
||||
public int getTimeOut() {
|
||||
return this.timeOut;
|
||||
return timeOut;
|
||||
}
|
||||
|
||||
// PhysicalTransactionDelegate ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
private void afterBeginCallback() {
|
||||
if(this.timeOut > 0) {
|
||||
transactionCoordinatorOwner.setTransactionTimeOut( this.timeOut );
|
||||
if ( timeOut > 0 ) {
|
||||
transactionCoordinatorOwner.setTransactionTimeOut( timeOut );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -17,12 +17,14 @@ import java.util.concurrent.Callable;
|
|||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.engine.jdbc.connections.spi.JdbcConnectionAccess;
|
||||
import org.hibernate.engine.jdbc.spi.SqlExceptionHelper;
|
||||
import org.hibernate.resource.jdbc.spi.JdbcSessionOwner;
|
||||
import org.hibernate.resource.transaction.spi.IsolationDelegate;
|
||||
import org.hibernate.internal.CoreLogging;
|
||||
import org.hibernate.internal.CoreMessageLogger;
|
||||
import org.hibernate.internal.util.ExceptionHelper;
|
||||
import org.hibernate.jdbc.WorkExecutor;
|
||||
import org.hibernate.jdbc.WorkExecutorVisitable;
|
||||
import org.hibernate.resource.transaction.spi.TransactionCoordinatorOwner;
|
||||
|
||||
/**
|
||||
* An isolation delegate for JTA environments.
|
||||
|
@ -36,6 +38,18 @@ public class JtaIsolationDelegate implements IsolationDelegate {
|
|||
private final SqlExceptionHelper sqlExceptionHelper;
|
||||
private final TransactionManager transactionManager;
|
||||
|
||||
public JtaIsolationDelegate(TransactionCoordinatorOwner transactionCoordinatorOwner, TransactionManager transactionManager) {
|
||||
this( transactionCoordinatorOwner.getJdbcSessionOwner(), transactionManager );
|
||||
}
|
||||
|
||||
public JtaIsolationDelegate(JdbcSessionOwner jdbcSessionOwner, TransactionManager transactionManager) {
|
||||
this(
|
||||
jdbcSessionOwner.getJdbcConnectionAccess(),
|
||||
jdbcSessionOwner.getJdbcSessionContext().getJdbcServices().getSqlExceptionHelper(),
|
||||
transactionManager
|
||||
);
|
||||
}
|
||||
|
||||
public JtaIsolationDelegate(
|
||||
JdbcConnectionAccess connectionAccess,
|
||||
SqlExceptionHelper sqlExceptionHelper,
|
||||
|
@ -46,74 +60,53 @@ public class JtaIsolationDelegate implements IsolationDelegate {
|
|||
}
|
||||
|
||||
protected JdbcConnectionAccess jdbcConnectionAccess() {
|
||||
return this.connectionAccess;
|
||||
return connectionAccess;
|
||||
}
|
||||
|
||||
protected SqlExceptionHelper sqlExceptionHelper() {
|
||||
return this.sqlExceptionHelper;
|
||||
return sqlExceptionHelper;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T delegateWork(final WorkExecutorVisitable<T> work, final boolean transacted) throws HibernateException {
|
||||
return doInSuspendedTransaction(new HibernateCallable<T>() {
|
||||
@Override
|
||||
public T call() throws HibernateException {
|
||||
HibernateCallable<T> workCallable = new HibernateCallable<T>() {
|
||||
@Override
|
||||
public T call() throws HibernateException {
|
||||
return doTheWork(work);
|
||||
}
|
||||
};
|
||||
if ( transacted ) {
|
||||
return doInNewTransaction( workCallable, transactionManager );
|
||||
}
|
||||
else {
|
||||
return workCallable.call();
|
||||
}
|
||||
}
|
||||
});
|
||||
return doInSuspendedTransaction(
|
||||
() -> transacted
|
||||
? doInNewTransaction( () -> doTheWork( work ), transactionManager )
|
||||
: doTheWork( work )
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T delegateCallable(final Callable<T> callable, final boolean transacted) throws HibernateException {
|
||||
return doInSuspendedTransaction(new HibernateCallable<T>() {
|
||||
@Override
|
||||
public T call() throws HibernateException {
|
||||
HibernateCallable<T> workCallable = new HibernateCallable<T>() {
|
||||
@Override
|
||||
public T call() throws HibernateException {
|
||||
try {
|
||||
return callable.call();
|
||||
}
|
||||
catch (HibernateException e) {
|
||||
throw e;
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new HibernateException(e);
|
||||
}
|
||||
}
|
||||
};
|
||||
if ( transacted ) {
|
||||
return doInNewTransaction( workCallable, transactionManager );
|
||||
}
|
||||
else {
|
||||
return workCallable.call();
|
||||
}
|
||||
}
|
||||
});
|
||||
return doInSuspendedTransaction(
|
||||
() -> transacted
|
||||
? doInNewTransaction( () -> call( callable ), transactionManager )
|
||||
: call( callable ));
|
||||
}
|
||||
|
||||
private static <T> T call(final Callable<T> callable) {
|
||||
try {
|
||||
return callable.call();
|
||||
}
|
||||
catch ( HibernateException e ) {
|
||||
throw e;
|
||||
}
|
||||
catch ( Exception e ) {
|
||||
throw new HibernateException( e );
|
||||
}
|
||||
}
|
||||
|
||||
private <T> T doInSuspendedTransaction(HibernateCallable<T> callable) {
|
||||
Throwable originalException = null;
|
||||
try {
|
||||
// First we suspend any current JTA transaction
|
||||
Transaction surroundingTransaction = transactionManager.suspend();
|
||||
final Transaction surroundingTransaction = transactionManager.suspend();
|
||||
LOG.debugf( "Surrounding JTA transaction suspended [%s]", surroundingTransaction );
|
||||
|
||||
try {
|
||||
return callable.call();
|
||||
}
|
||||
catch (Throwable t1) {
|
||||
catch ( Throwable t1 ) {
|
||||
originalException = t1;
|
||||
}
|
||||
finally {
|
||||
|
@ -121,7 +114,7 @@ public class JtaIsolationDelegate implements IsolationDelegate {
|
|||
transactionManager.resume( surroundingTransaction );
|
||||
LOG.debugf( "Surrounding JTA transaction resumed [%s]", surroundingTransaction );
|
||||
}
|
||||
catch (Throwable t2) {
|
||||
catch ( Throwable t2 ) {
|
||||
// if the actually work had an error use that, otherwise error based on t
|
||||
if ( originalException == null ) {
|
||||
originalException = new HibernateException( "Unable to resume previously suspended transaction", t2 );
|
||||
|
@ -132,7 +125,7 @@ public class JtaIsolationDelegate implements IsolationDelegate {
|
|||
}
|
||||
}
|
||||
}
|
||||
catch (SystemException e) {
|
||||
catch ( SystemException e ) {
|
||||
originalException = new HibernateException( "Unable to suspend current JTA transaction", e );
|
||||
}
|
||||
|
||||
|
@ -144,27 +137,23 @@ public class JtaIsolationDelegate implements IsolationDelegate {
|
|||
try {
|
||||
// start the new isolated transaction
|
||||
transactionManager.begin();
|
||||
|
||||
try {
|
||||
T result = callable.call();
|
||||
// if everything went ok, commit the isolated transaction
|
||||
transactionManager.commit();
|
||||
return result;
|
||||
}
|
||||
catch (Exception e) {
|
||||
catch ( Exception e ) {
|
||||
try {
|
||||
transactionManager.rollback();
|
||||
}
|
||||
catch (Exception ignore) {
|
||||
LOG.unableToRollbackIsolatedTransaction( e, ignore );
|
||||
catch ( Exception exception ) {
|
||||
LOG.unableToRollbackIsolatedTransaction( e, exception );
|
||||
}
|
||||
throw new HibernateException( "Could not apply work", e );
|
||||
}
|
||||
}
|
||||
catch (SystemException e) {
|
||||
throw new HibernateException( "Unable to start isolated transaction", e );
|
||||
}
|
||||
catch (NotSupportedException e) {
|
||||
catch ( SystemException | NotSupportedException e ) {
|
||||
throw new HibernateException( "Unable to start isolated transaction", e );
|
||||
}
|
||||
}
|
||||
|
@ -177,10 +166,10 @@ public class JtaIsolationDelegate implements IsolationDelegate {
|
|||
// do the actual work
|
||||
return work.accept( new WorkExecutor<>(), connection );
|
||||
}
|
||||
catch (HibernateException e) {
|
||||
catch ( HibernateException e ) {
|
||||
throw e;
|
||||
}
|
||||
catch (Exception e) {
|
||||
catch ( Exception e ) {
|
||||
throw new HibernateException( "Unable to perform isolated work", e );
|
||||
}
|
||||
finally {
|
||||
|
@ -188,8 +177,8 @@ public class JtaIsolationDelegate implements IsolationDelegate {
|
|||
// no matter what, release the connection (handle)
|
||||
jdbcConnectionAccess().releaseConnection( connection );
|
||||
}
|
||||
catch (Throwable ignore) {
|
||||
LOG.unableToReleaseIsolatedConnection( ignore );
|
||||
catch ( Throwable throwable ) {
|
||||
LOG.unableToReleaseIsolatedConnection( throwable );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,6 +16,8 @@ import org.hibernate.service.spi.ServiceRegistryAwareService;
|
|||
import org.hibernate.service.spi.ServiceRegistryImplementor;
|
||||
import org.hibernate.tool.schema.internal.exec.JdbcContext;
|
||||
|
||||
import static org.hibernate.resource.jdbc.spi.PhysicalConnectionHandlingMode.DELAYED_ACQUISITION_AND_RELEASE_AFTER_STATEMENT;
|
||||
|
||||
/**
|
||||
* Concrete builder for JTA-based TransactionCoordinator instances.
|
||||
*
|
||||
|
@ -44,8 +46,8 @@ public class JtaTransactionCoordinatorBuilderImpl implements TransactionCoordina
|
|||
|
||||
@Override
|
||||
public PhysicalConnectionHandlingMode getDefaultConnectionHandlingMode() {
|
||||
// todo : I want to change this to PhysicalConnectionHandlingMode#IMMEDIATE_ACQUISITION_AND_HOLD
|
||||
return PhysicalConnectionHandlingMode.DELAYED_ACQUISITION_AND_RELEASE_AFTER_STATEMENT;
|
||||
// todo : I want to change this to IMMEDIATE_ACQUISITION_AND_HOLD
|
||||
return DELAYED_ACQUISITION_AND_RELEASE_AFTER_STATEMENT;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -55,7 +57,7 @@ public class JtaTransactionCoordinatorBuilderImpl implements TransactionCoordina
|
|||
|
||||
@Override
|
||||
public void injectServices(ServiceRegistryImplementor serviceRegistry) {
|
||||
this.jtaPlatform = serviceRegistry.getService( JtaPlatform.class );
|
||||
jtaPlatform = serviceRegistry.getService( JtaPlatform.class );
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -7,19 +7,15 @@
|
|||
package org.hibernate.resource.transaction.backend.jta.internal;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import jakarta.transaction.Status;
|
||||
import jakarta.transaction.TransactionManager;
|
||||
import jakarta.transaction.UserTransaction;
|
||||
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.boot.spi.SessionFactoryOptions;
|
||||
import org.hibernate.engine.transaction.jta.platform.spi.JtaPlatform;
|
||||
import org.hibernate.resource.transaction.spi.IsolationDelegate;
|
||||
import org.hibernate.jpa.spi.JpaCompliance;
|
||||
import org.hibernate.resource.jdbc.spi.JdbcSessionContext;
|
||||
import org.hibernate.resource.jdbc.spi.JdbcSessionOwner;
|
||||
import org.hibernate.resource.transaction.TransactionRequiredForJoinException;
|
||||
import org.hibernate.resource.transaction.backend.jta.internal.synchronization.RegisteredSynchronization;
|
||||
import org.hibernate.resource.transaction.backend.jta.internal.synchronization.SynchronizationCallbackCoordinator;
|
||||
|
@ -36,7 +32,11 @@ import org.hibernate.resource.transaction.spi.TransactionStatus;
|
|||
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
import static java.util.Collections.addAll;
|
||||
import static java.util.Collections.emptyList;
|
||||
import static org.hibernate.internal.CoreLogging.logger;
|
||||
import static org.hibernate.resource.transaction.spi.TransactionStatus.ACTIVE;
|
||||
import static org.hibernate.resource.transaction.spi.TransactionStatus.NOT_ACTIVE;
|
||||
|
||||
/**
|
||||
* An implementation of TransactionCoordinator based on managing a transaction through the JTA API (either TM or UT)
|
||||
|
@ -83,9 +83,8 @@ public class JtaTransactionCoordinatorImpl implements TransactionCoordinator, Sy
|
|||
|
||||
this.jtaPlatform = jtaPlatform;
|
||||
|
||||
final SessionFactoryOptions sessionFactoryOptions = jdbcSessionContext.getSessionFactory().getSessionFactoryOptions();
|
||||
this.preferUserTransactions = sessionFactoryOptions.isPreferUserTransaction();
|
||||
this.performJtaThreadTracking = sessionFactoryOptions.isJtaTrackByThread();
|
||||
this.preferUserTransactions = jdbcSessionContext.isPreferUserTransaction();
|
||||
this.performJtaThreadTracking = jdbcSessionContext.isJtaTrackByThread();
|
||||
|
||||
synchronizationRegistered = false;
|
||||
|
||||
|
@ -109,7 +108,7 @@ public class JtaTransactionCoordinatorImpl implements TransactionCoordinator, Sy
|
|||
|
||||
if ( observers != null ) {
|
||||
this.observers = new ArrayList<>( observers.length );
|
||||
Collections.addAll( this.observers, observers );
|
||||
addAll( this.observers, observers );
|
||||
}
|
||||
|
||||
synchronizationRegistered = false;
|
||||
|
@ -125,12 +124,7 @@ public class JtaTransactionCoordinatorImpl implements TransactionCoordinator, Sy
|
|||
* @return TransactionObserver
|
||||
*/
|
||||
private Iterable<TransactionObserver> observers() {
|
||||
if ( this.observers == null ) {
|
||||
return Collections.EMPTY_LIST;
|
||||
}
|
||||
else {
|
||||
return new ArrayList<>( this.observers );
|
||||
}
|
||||
return observers == null ? emptyList() : new ArrayList<>( observers );
|
||||
}
|
||||
|
||||
public SynchronizationCallbackCoordinator getSynchronizationCallbackCoordinator() {
|
||||
|
@ -186,7 +180,7 @@ public class JtaTransactionCoordinatorImpl implements TransactionCoordinator, Sy
|
|||
return;
|
||||
}
|
||||
|
||||
if ( getTransactionDriverControl().getStatus() != TransactionStatus.ACTIVE ) {
|
||||
if ( getTransactionDriverControl().getStatus() != ACTIVE ) {
|
||||
throw new TransactionRequiredForJoinException(
|
||||
"Explicitly joining a JTA transaction requires a JTA transaction be currently active"
|
||||
);
|
||||
|
@ -217,11 +211,7 @@ public class JtaTransactionCoordinatorImpl implements TransactionCoordinator, Sy
|
|||
|
||||
@Override
|
||||
public JpaCompliance getJpaCompliance() {
|
||||
return transactionCoordinatorOwner.getJdbcSessionOwner()
|
||||
.getJdbcSessionContext()
|
||||
.getSessionFactory()
|
||||
.getSessionFactoryOptions()
|
||||
.getJpaCompliance();
|
||||
return transactionCoordinatorOwner.getJdbcSessionOwner().getJdbcSessionContext().getJpaCompliance();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -271,8 +261,8 @@ public class JtaTransactionCoordinatorImpl implements TransactionCoordinator, Sy
|
|||
return new JtaTransactionAdapterUserTransactionImpl( userTransaction );
|
||||
}
|
||||
}
|
||||
catch (Exception ignore) {
|
||||
log.debugf( "JtaPlatform#retrieveUserTransaction threw an exception [%s]", ignore.getMessage() );
|
||||
catch ( Exception exception ) {
|
||||
log.debugf( "JtaPlatform#retrieveUserTransaction threw an exception [%s]", exception.getMessage() );
|
||||
}
|
||||
|
||||
return null;
|
||||
|
@ -288,8 +278,8 @@ public class JtaTransactionCoordinatorImpl implements TransactionCoordinator, Sy
|
|||
return new JtaTransactionAdapterTransactionManagerImpl( transactionManager );
|
||||
}
|
||||
}
|
||||
catch (Exception ignore) {
|
||||
log.debugf( "JtaPlatform#retrieveTransactionManager threw an exception [%s]", ignore.getMessage() );
|
||||
catch ( Exception exception ) {
|
||||
log.debugf( "JtaPlatform#retrieveTransactionManager threw an exception [%s]", exception.getMessage() );
|
||||
}
|
||||
|
||||
return null;
|
||||
|
@ -306,25 +296,17 @@ public class JtaTransactionCoordinatorImpl implements TransactionCoordinator, Sy
|
|||
}
|
||||
|
||||
public boolean isJtaTransactionCurrentlyActive() {
|
||||
return getTransactionDriverControl().getStatus() == TransactionStatus.ACTIVE;
|
||||
return getTransactionDriverControl().getStatus() == ACTIVE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IsolationDelegate createIsolationDelegate() {
|
||||
final JdbcSessionOwner jdbcSessionOwner = transactionCoordinatorOwner.getJdbcSessionOwner();
|
||||
|
||||
return new JtaIsolationDelegate(
|
||||
jdbcSessionOwner.getJdbcConnectionAccess(),
|
||||
jdbcSessionOwner.getJdbcSessionContext()
|
||||
.getSessionFactory()
|
||||
.getFastSessionServices().jdbcServices.getSqlExceptionHelper(),
|
||||
jtaPlatform.retrieveTransactionManager()
|
||||
);
|
||||
return new JtaIsolationDelegate( transactionCoordinatorOwner, jtaPlatform.retrieveTransactionManager() );
|
||||
}
|
||||
|
||||
@Override
|
||||
public TransactionCoordinatorBuilder getTransactionCoordinatorBuilder() {
|
||||
return this.transactionCoordinatorBuilder;
|
||||
return transactionCoordinatorBuilder;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -335,7 +317,7 @@ public class JtaTransactionCoordinatorImpl implements TransactionCoordinator, Sy
|
|||
|
||||
@Override
|
||||
public int getTimeOut() {
|
||||
return this.timeOut;
|
||||
return timeOut;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -353,14 +335,10 @@ public class JtaTransactionCoordinatorImpl implements TransactionCoordinator, Sy
|
|||
try {
|
||||
transactionCoordinatorOwner.beforeTransactionCompletion();
|
||||
}
|
||||
catch (HibernateException e) {
|
||||
catch ( Exception e ) {
|
||||
physicalTransactionDelegate.markRollbackOnly();
|
||||
throw e;
|
||||
}
|
||||
catch (RuntimeException re) {
|
||||
physicalTransactionDelegate.markRollbackOnly();
|
||||
throw re;
|
||||
}
|
||||
finally {
|
||||
synchronizationRegistry.notifySynchronizationsBeforeTransactionCompletion();
|
||||
for ( TransactionObserver observer : observers() ) {
|
||||
|
@ -390,8 +368,8 @@ public class JtaTransactionCoordinatorImpl implements TransactionCoordinator, Sy
|
|||
}
|
||||
|
||||
public void addObserver(TransactionObserver observer) {
|
||||
if ( this.observers == null ) {
|
||||
this.observers = new ArrayList<>( 3 ); //These lists are typically very small.
|
||||
if ( observers == null ) {
|
||||
observers = new ArrayList<>( 3 ); //These lists are typically very small.
|
||||
}
|
||||
observers.add( observer );
|
||||
}
|
||||
|
@ -460,7 +438,7 @@ public class JtaTransactionCoordinatorImpl implements TransactionCoordinator, Sy
|
|||
|
||||
@Override
|
||||
public void markRollbackOnly() {
|
||||
if ( jtaTransactionAdapter.getStatus() != TransactionStatus.NOT_ACTIVE ) {
|
||||
if ( jtaTransactionAdapter.getStatus() != NOT_ACTIVE ) {
|
||||
jtaTransactionAdapter.markRollbackOnly();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,6 +8,9 @@ package org.hibernate.resource.transaction.spi;
|
|||
|
||||
import org.hibernate.jpa.spi.JpaCompliance;
|
||||
|
||||
import static org.hibernate.resource.transaction.spi.TransactionStatus.ACTIVE;
|
||||
import static org.hibernate.resource.transaction.spi.TransactionStatus.MARKED_ROLLBACK;
|
||||
|
||||
/**
|
||||
* Models the coordination of all transaction related flows.
|
||||
*
|
||||
|
@ -52,14 +55,14 @@ public interface TransactionCoordinator {
|
|||
boolean isJoined();
|
||||
|
||||
/**
|
||||
* Used by owner of the JdbcSession as a means to indicate that implicit joining should be done if needed.
|
||||
* Used by owner of the "JDBC session" as a means to indicate that implicit joining should be done if needed.
|
||||
*/
|
||||
void pulse();
|
||||
|
||||
/**
|
||||
* Is this transaction still active?
|
||||
* <p>
|
||||
* Answers on a best effort basis. For example, in the case of JDBC based transactions we cannot know that a
|
||||
* Answers on a best-effort basis. For example, in the case of JDBC based transactions we cannot know that a
|
||||
* transaction is active when it is initiated directly through the JDBC {@link java.sql.Connection}, only when
|
||||
* it is initiated from here.
|
||||
*
|
||||
|
@ -101,7 +104,8 @@ public interface TransactionCoordinator {
|
|||
}
|
||||
|
||||
default boolean isTransactionActive(boolean isMarkedRollbackConsideredActive) {
|
||||
return isJoined() && getTransactionDriverControl().isActive( isMarkedRollbackConsideredActive );
|
||||
return isJoined()
|
||||
&& getTransactionDriverControl().isActive( isMarkedRollbackConsideredActive );
|
||||
}
|
||||
|
||||
default void invalidate(){}
|
||||
|
@ -134,8 +138,8 @@ public interface TransactionCoordinator {
|
|||
|
||||
default boolean isActive(boolean isMarkedRollbackConsideredActive) {
|
||||
final TransactionStatus status = getStatus();
|
||||
return TransactionStatus.ACTIVE == status
|
||||
|| ( isMarkedRollbackConsideredActive && TransactionStatus.MARKED_ROLLBACK == status );
|
||||
return status == ACTIVE
|
||||
|| isMarkedRollbackConsideredActive && status == MARKED_ROLLBACK;
|
||||
}
|
||||
|
||||
// todo : org.hibernate.Transaction will need access to register local Synchronizations.
|
||||
|
|
|
@ -127,8 +127,7 @@ public abstract class AbstractBatchingTest {
|
|||
// a legacy implementation does not call abortBatch().
|
||||
final JdbcServices jdbcServices = jdbcCoordinator.getJdbcSessionOwner()
|
||||
.getJdbcSessionContext()
|
||||
.getServiceRegistry()
|
||||
.getService( JdbcServices.class );
|
||||
.getJdbcServices();
|
||||
throw jdbcServices.getSqlExceptionHelper().convert(
|
||||
new SQLException( "fake SQLException" ),
|
||||
"could not perform addBatch",
|
||||
|
|
Loading…
Reference in New Issue