下面列出了org.hibernate.jdbc.JDBCContext#org.hibernate.ConnectionReleaseMode 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
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;
}
}
public JDBCContext(Context owner, Connection connection, Interceptor interceptor) {
this.owner = owner;
this.connectionManager = new ConnectionManager(
owner.getFactory(),
this,
owner.getConnectionReleaseMode(),
connection,
interceptor
);
final boolean registerSynchronization = owner.isAutoCloseSessionEnabled()
|| owner.isFlushBeforeCompletionEnabled()
|| owner.getConnectionReleaseMode() == ConnectionReleaseMode.AFTER_TRANSACTION;
if ( registerSynchronization ) {
registerSynchronizationIfPossible();
}
}
/**
* Constructs a ConnectionManager.
* <p/>
* This is the form used internally.
*
* @param factory The SessionFactory.
* @param callback An observer for internal state change.
* @param releaseMode The mode by which to release JDBC connections.
* @param connection An externally supplied connection.
*/
public ConnectionManager(
SessionFactoryImplementor factory,
Callback callback,
ConnectionReleaseMode releaseMode,
Connection connection,
Interceptor interceptor) {
this.factory = factory;
this.callback = callback;
this.interceptor = interceptor;
this.batcher = factory.getSettings().getBatcherFactory().createBatcher( this, interceptor );
this.connection = connection;
wasConnectionSupplied = ( connection != null );
this.releaseMode = wasConnectionSupplied ? ConnectionReleaseMode.ON_CLOSE : releaseMode;
}
/**
* Private constructor used exclusively from custom serialization
*/
private ConnectionManager(
SessionFactoryImplementor factory,
Callback callback,
ConnectionReleaseMode releaseMode,
Interceptor interceptor,
boolean wasConnectionSupplied,
boolean isClosed) {
this.factory = factory;
this.callback = callback;
this.interceptor = interceptor;
this.batcher = factory.getSettings().getBatcherFactory().createBatcher( this, interceptor );
this.wasConnectionSupplied = wasConnectionSupplied;
this.isClosed = isClosed;
this.releaseMode = wasConnectionSupplied ? ConnectionReleaseMode.ON_CLOSE : releaseMode;
}
/**
* Will connections be released after each statement execution?
* <p/>
* Connections will be released after each statement if either:<ul>
* <li>the defined release-mode is {@link ConnectionReleaseMode#AFTER_STATEMENT}; or
* <li>the defined release-mode is {@link ConnectionReleaseMode#AFTER_TRANSACTION} but
* we are in auto-commit mode.
* <p/>
* release-mode = {@link ConnectionReleaseMode#ON_CLOSE} should [b]never[/b] release
* a connection.
*
* @return True if the connections will be released after each statement; false otherwise.
*/
public boolean isAggressiveRelease() {
if ( releaseMode == ConnectionReleaseMode.AFTER_STATEMENT ) {
return true;
}
else if ( releaseMode == ConnectionReleaseMode.AFTER_TRANSACTION ) {
boolean inAutoCommitState;
try {
inAutoCommitState = isAutoCommit()&& !callback.isTransactionInProgress();
}
catch( SQLException e ) {
// assume we are in an auto-commit state
inAutoCommitState = true;
}
return inAutoCommitState;
}
return false;
}
/**
* Modified version of {@link #isAggressiveRelease} which does not force a
* transaction check. This is solely used from our {@link #afterTransaction}
* callback, so no need to do the check; plus it seems to cause problems on
* websphere (god i love websphere ;)
* </p>
* It uses this information to decide if an aggressive release was skipped
* do to open resources, and if so forces a release.
*
* @return True if the connections will be released after each statement; false otherwise.
*/
private boolean isAggressiveReleaseNoTransactionCheck() {
if ( releaseMode == ConnectionReleaseMode.AFTER_STATEMENT ) {
return true;
}
else {
boolean inAutoCommitState;
try {
inAutoCommitState = isAutoCommit();
}
catch( SQLException e ) {
// assume we are in an auto-commit state
inAutoCommitState = true;
}
return releaseMode == ConnectionReleaseMode.AFTER_TRANSACTION && inAutoCommitState;
}
}
public org.hibernate.classic.Session openSession(
final Connection connection,
final boolean flushBeforeCompletionEnabled,
final boolean autoCloseSessionEnabled,
final ConnectionReleaseMode connectionReleaseMode) throws HibernateException {
return new SessionImpl(
connection,
this,
true,
settings.getCacheProvider().nextTimestamp(),
interceptor,
settings.getDefaultEntityMode(),
flushBeforeCompletionEnabled,
autoCloseSessionEnabled,
connectionReleaseMode
);
}
/**
* Return whether the given Hibernate Session will always hold the same
* JDBC Connection. This is used to check whether the transaction manager
* can safely prepare and clean up the JDBC Connection used for a transaction.
* <p>The default implementation checks the Session's connection release mode
* to be "on_close".
* @param session the Hibernate Session to check
* @see ConnectionReleaseMode#ON_CLOSE
*/
@SuppressWarnings("deprecation")
protected boolean isSameConnectionForEntireSession(Session session) {
if (!(session instanceof SessionImplementor)) {
// The best we can do is to assume we're safe.
return true;
}
ConnectionReleaseMode releaseMode =
((SessionImplementor) session).getJdbcCoordinator().getConnectionReleaseMode();
return ConnectionReleaseMode.ON_CLOSE.equals(releaseMode);
}
/**
* Return whether the given Hibernate Session will always hold the same
* JDBC Connection. This is used to check whether the transaction manager
* can safely prepare and clean up the JDBC Connection used for a transaction.
* <p>The default implementation checks the Session's connection release mode
* to be "on_close".
* @param session the Hibernate Session to check
* @see ConnectionReleaseMode#ON_CLOSE
*/
@SuppressWarnings("deprecation")
protected boolean isSameConnectionForEntireSession(Session session) {
if (!(session instanceof SessionImplementor)) {
// The best we can do is to assume we're safe.
return true;
}
ConnectionReleaseMode releaseMode =
((SessionImplementor) session).getJdbcCoordinator().getConnectionReleaseMode();
return ConnectionReleaseMode.ON_CLOSE.equals(releaseMode);
}
/**
* Return whether the given Hibernate Session will always hold the same
* JDBC Connection. This is used to check whether the transaction manager
* can safely prepare and clean up the JDBC Connection used for a transaction.
* <p>The default implementation checks the Session's connection release mode
* to be "on_close".
* @param session the Hibernate Session to check
* @see ConnectionReleaseMode#ON_CLOSE
*/
@SuppressWarnings("deprecation")
protected boolean isSameConnectionForEntireSession(Session session) {
if (!(session instanceof SessionImplementor)) {
// The best we can do is to assume we're safe.
return true;
}
ConnectionReleaseMode releaseMode =
((SessionImplementor) session).getJdbcCoordinator().getConnectionReleaseMode();
return ConnectionReleaseMode.ON_CLOSE.equals(releaseMode);
}
private PhysicalConnectionHandlingMode determineConnectionHandlingMode(
PhysicalConnectionHandlingMode connectionHandlingMode,
JdbcConnectionAccess jdbcConnectionAccess) {
if ( connectionHandlingMode.getReleaseMode() == ConnectionReleaseMode.AFTER_STATEMENT
&& !jdbcConnectionAccess.supportsAggressiveRelease() ) {
return PhysicalConnectionHandlingMode.DELAYED_ACQUISITION_AND_RELEASE_AFTER_TRANSACTION;
}
return connectionHandlingMode;
}
@Override
public void afterStatement() {
super.afterStatement();
if ( connectionHandlingMode.getReleaseMode() == ConnectionReleaseMode.AFTER_STATEMENT ) {
if ( getResourceRegistry().hasRegisteredResources() ) {
log.debug( "Skipping aggressive release of JDBC Connection after-statement due to held resources" );
}
else {
log.debug( "Initiating JDBC connection release from afterStatement" );
releaseConnection();
}
}
}
@Override
public void afterTransaction() {
super.afterTransaction();
if ( connectionHandlingMode.getReleaseMode() != ConnectionReleaseMode.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
log.debug( "Initiating JDBC connection release from afterTransaction" );
releaseConnection();
}
}
@Override
public void afterStatementExecution() {
LOG.tracev( "Starting after statement execution processing [{0}]", getConnectionReleaseMode() );
if ( getConnectionReleaseMode() == ConnectionReleaseMode.AFTER_STATEMENT ) {
if ( ! releasesEnabled ) {
LOG.debug( "Skipping aggressive release due to manual disabling" );
return;
}
if ( hasRegisteredResources() ) {
LOG.debug( "Skipping aggressive release due to registered resources" );
return;
}
getLogicalConnection().afterStatement();
}
}
@Override
public void afterTransaction() {
transactionTimeOutInstant = -1;
if ( getConnectionReleaseMode() == ConnectionReleaseMode.AFTER_STATEMENT ||
getConnectionReleaseMode() == ConnectionReleaseMode.AFTER_TRANSACTION ) {
this.logicalConnection.afterTransaction();
}
}
@SuppressWarnings("deprecation")
private PhysicalConnectionHandlingMode interpretConnectionHandlingMode(
Map configurationSettings,
StandardServiceRegistry serviceRegistry) {
final PhysicalConnectionHandlingMode specifiedHandlingMode = PhysicalConnectionHandlingMode.interpret(
configurationSettings.get( CONNECTION_HANDLING )
);
if ( specifiedHandlingMode != null ) {
return specifiedHandlingMode;
}
final TransactionCoordinatorBuilder transactionCoordinatorBuilder = serviceRegistry.getService( TransactionCoordinatorBuilder.class );
// see if the deprecated ConnectionAcquisitionMode/ConnectionReleaseMode were used..
final ConnectionAcquisitionMode specifiedAcquisitionMode = ConnectionAcquisitionMode.interpret(
configurationSettings.get( ACQUIRE_CONNECTIONS )
);
final ConnectionReleaseMode specifiedReleaseMode = ConnectionReleaseMode.interpret(
configurationSettings.get( RELEASE_CONNECTIONS )
);
if ( specifiedAcquisitionMode != null || specifiedReleaseMode != null ) {
return interpretConnectionHandlingMode( specifiedAcquisitionMode, specifiedReleaseMode, configurationSettings, transactionCoordinatorBuilder );
}
return transactionCoordinatorBuilder.getDefaultConnectionHandlingMode();
}
@SuppressWarnings("deprecation")
private PhysicalConnectionHandlingMode interpretConnectionHandlingMode(
ConnectionAcquisitionMode specifiedAcquisitionMode,
ConnectionReleaseMode specifiedReleaseMode,
Map configurationSettings,
TransactionCoordinatorBuilder transactionCoordinatorBuilder) {
DeprecationLogger.DEPRECATION_LOGGER.logUseOfDeprecatedConnectionHandlingSettings();
final ConnectionAcquisitionMode effectiveAcquisitionMode = specifiedAcquisitionMode == null
? ConnectionAcquisitionMode.AS_NEEDED
: specifiedAcquisitionMode;
final ConnectionReleaseMode effectiveReleaseMode;
if ( specifiedReleaseMode == null ) {
// check the actual setting. If we get in here it *should* be "auto" or null
final String releaseModeName = ConfigurationHelper.getString( RELEASE_CONNECTIONS, configurationSettings, "auto" );
assert "auto".equalsIgnoreCase( releaseModeName );
// nothing was specified (or someone happened to configure the "magic" value)
if ( effectiveAcquisitionMode == ConnectionAcquisitionMode.IMMEDIATELY ) {
effectiveReleaseMode = ConnectionReleaseMode.ON_CLOSE;
}
else {
effectiveReleaseMode = transactionCoordinatorBuilder.getDefaultConnectionReleaseMode();
}
}
else {
effectiveReleaseMode = specifiedReleaseMode;
}
return PhysicalConnectionHandlingMode.interpret( effectiveAcquisitionMode, effectiveReleaseMode );
}
public void applyConnectionReleaseMode(ConnectionReleaseMode connectionReleaseMode) {
if ( this.connectionHandlingMode == null ) {
this.connectionHandlingMode = PhysicalConnectionHandlingMode.interpret(
ConnectionAcquisitionMode.AS_NEEDED,
connectionReleaseMode
);
}
else {
this.connectionHandlingMode = PhysicalConnectionHandlingMode.interpret(
this.connectionHandlingMode.getAcquisitionMode(),
connectionReleaseMode
);
}
}
/**
* Return whether the given Hibernate Session will always hold the same
* JDBC Connection. This is used to check whether the transaction manager
* can safely prepare and clean up the JDBC Connection used for a transaction.
* <p>The default implementation checks the Session's connection release mode
* to be "on_close".
* @param session the Hibernate Session to check
* @see ConnectionReleaseMode#ON_CLOSE
*/
protected boolean isSameConnectionForEntireSession(Session session) {
if (!(session instanceof SessionImplementor)) {
// The best we can do is to assume we're safe.
return true;
}
ConnectionReleaseMode releaseMode =
((SessionImplementor) session).getJdbcCoordinator().getConnectionReleaseMode();
return ConnectionReleaseMode.ON_CLOSE.equals(releaseMode);
}
public static ConnectionManager deserialize(
ObjectInputStream ois,
SessionFactoryImplementor factory,
Interceptor interceptor,
ConnectionReleaseMode connectionReleaseMode,
JDBCContext jdbcContext) throws IOException {
return new ConnectionManager(
factory,
jdbcContext,
connectionReleaseMode,
interceptor,
ois.readBoolean(),
ois.readBoolean()
);
}
/**
* Constructor used for openSession(...) processing, as well as construction
* of sessions for getCurrentSession().
*
* @param connection The user-supplied connection to use for this session.
* @param factory The factory from which this session was obtained
* @param autoclose NOT USED
* @param timestamp The timestamp for this session
* @param interceptor The interceptor to be applied to this session
* @param entityMode The entity-mode for this session
* @param flushBeforeCompletionEnabled Should we auto flush before completion of transaction
* @param autoCloseSessionEnabled Should we auto close after completion of transaction
* @param connectionReleaseMode The mode by which we should release JDBC connections.
*/
SessionImpl(
final Connection connection,
final SessionFactoryImpl factory,
final boolean autoclose,
final long timestamp,
final Interceptor interceptor,
final EntityMode entityMode,
final boolean flushBeforeCompletionEnabled,
final boolean autoCloseSessionEnabled,
final ConnectionReleaseMode connectionReleaseMode) {
super( factory );
this.rootSession = null;
this.timestamp = timestamp;
this.entityMode = entityMode;
this.interceptor = interceptor;
this.listeners = factory.getEventListeners();
this.actionQueue = new ActionQueue( this );
this.persistenceContext = new StatefulPersistenceContext( this );
this.flushBeforeCompletionEnabled = flushBeforeCompletionEnabled;
this.autoCloseSessionEnabled = autoCloseSessionEnabled;
this.connectionReleaseMode = connectionReleaseMode;
this.jdbcContext = new JDBCContext( this, connection, interceptor );
if ( factory.getStatistics().isStatisticsEnabled() ) {
factory.getStatisticsImplementor().openSession();
}
if ( log.isDebugEnabled() ) {
log.debug( "opened session at timestamp: " + timestamp );
}
}
public org.hibernate.classic.Session openTemporarySession() throws HibernateException {
return new SessionImpl(
null,
this,
true,
settings.getCacheProvider().nextTimestamp(),
interceptor,
settings.getDefaultEntityMode(),
false,
false,
ConnectionReleaseMode.AFTER_STATEMENT
);
}
public void configure(Configuration cfg) {
cfg.setProperty( Environment.CONNECTION_PROVIDER, DummyConnectionProvider.class.getName() );
cfg.setProperty( Environment.TRANSACTION_MANAGER_STRATEGY, DummyTransactionManagerLookup.class.getName() );
cfg.setProperty( Environment.TRANSACTION_STRATEGY, CMTTransactionFactory.class.getName() );
cfg.setProperty( Environment.AUTO_CLOSE_SESSION, "true" );
cfg.setProperty( Environment.FLUSH_BEFORE_COMPLETION, "true" );
cfg.setProperty( Environment.RELEASE_CONNECTIONS, ConnectionReleaseMode.AFTER_STATEMENT.toString() );
cfg.setProperty( Environment.GENERATE_STATISTICS, "true" );
cfg.setProperty( Environment.USE_QUERY_CACHE, "true" );
cfg.setProperty( Environment.DEFAULT_ENTITY_MODE, EntityMode.MAP.toString() );
}
public void configure(Configuration cfg) {
super.configure( cfg );
cfg.setProperty( Environment.RELEASE_CONNECTIONS, ConnectionReleaseMode.AFTER_STATEMENT.toString() );
cfg.setProperty( Environment.CONNECTION_PROVIDER, DummyConnectionProvider.class.getName() );
cfg.setProperty( Environment.TRANSACTION_STRATEGY, CMTTransactionFactory.class.getName() );
cfg.setProperty( Environment.TRANSACTION_MANAGER_STRATEGY, DummyTransactionManagerLookup.class.getName() );
cfg.setProperty( Environment.GENERATE_STATISTICS, "true" );
cfg.setProperty( Environment.STATEMENT_BATCH_SIZE, "0" );
}
public ConnectionReleaseMode getConnectionReleaseMode() {
return sessionFactoryOptions.getConnectionReleaseMode();
}
/**
* @deprecated (since 5.2) Use {@link #getDefaultConnectionHandlingMode} instead
*/
@Deprecated
default ConnectionReleaseMode getDefaultConnectionReleaseMode() {
return getDefaultConnectionHandlingMode().getReleaseMode();
}
@Override
public ConnectionReleaseMode getConnectionReleaseMode() {
return connectionHandlingMode.getReleaseMode();
}
@Override
@SuppressWarnings("deprecation")
public ConnectionReleaseMode getConnectionReleaseMode() {
return delegate.getConnectionReleaseMode();
}
@SuppressWarnings("deprecation")
@Override
public T applyConnectionReleaseMode(ConnectionReleaseMode connectionReleaseMode) {
delegate.applyConnectionReleaseMode( connectionReleaseMode );
return getThis();
}
@Override
public ConnectionReleaseMode getConnectionReleaseMode() {
return getPhysicalConnectionHandlingMode().getReleaseMode();
}