HHH-9747 - Import initial reworking of transaction handling (based on JdbcSession work)
This commit is contained in:
parent
82b312dd21
commit
b476094d43
|
@ -148,5 +148,9 @@ public class EmptyInterceptor implements Interceptor, Serializable {
|
|||
@Override
|
||||
public void onCollectionUpdate(Object collection, Serializable key) throws CallbackException {
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String inspect(String sql) {
|
||||
return this.onPrepareStatement( sql );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@ package org.hibernate;
|
|||
import java.io.Serializable;
|
||||
import java.util.Iterator;
|
||||
|
||||
import org.hibernate.resource.jdbc.spi.StatementInspector;
|
||||
import org.hibernate.type.Type;
|
||||
|
||||
/**
|
||||
|
@ -52,7 +53,7 @@ import org.hibernate.type.Type;
|
|||
*
|
||||
* @author Gavin King
|
||||
*/
|
||||
public interface Interceptor {
|
||||
public interface Interceptor extends StatementInspector {
|
||||
/**
|
||||
* Called just before an object is initialized. The interceptor may change the <tt>state</tt>, which will
|
||||
* be propagated to the persistent object. Note that when this method is called, <tt>entity</tt> will be
|
||||
|
|
|
@ -25,7 +25,9 @@ package org.hibernate;
|
|||
|
||||
import javax.transaction.Synchronization;
|
||||
|
||||
import org.hibernate.engine.transaction.spi.IsolationDelegate;
|
||||
import org.hibernate.engine.transaction.spi.LocalStatus;
|
||||
import org.hibernate.resource.transaction.spi.TransactionStatus;
|
||||
|
||||
/**
|
||||
* Defines the contract for abstracting applications from the configured underlying means of transaction management.
|
||||
|
@ -44,12 +46,6 @@ import org.hibernate.engine.transaction.spi.LocalStatus;
|
|||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface Transaction {
|
||||
/**
|
||||
* Is this transaction the initiator of any underlying transaction?
|
||||
*
|
||||
* @return {@code true} if this transaction initiated the underlying transaction; {@code false} otherwise.
|
||||
*/
|
||||
public boolean isInitiator();
|
||||
|
||||
/**
|
||||
* Begin this transaction. No-op if the transaction has already been begun. Note that this is not necessarily
|
||||
|
@ -93,58 +89,7 @@ public interface Transaction {
|
|||
*
|
||||
* @return The current local status.
|
||||
*/
|
||||
public LocalStatus getLocalStatus();
|
||||
|
||||
/**
|
||||
* 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
|
||||
* transaction is active when it is initiated directly through the JDBC {@link java.sql.Connection}, only when
|
||||
* it is initiated from here.
|
||||
*
|
||||
* @return {@code true} if the transaction is still active; {@code false} otherwise.
|
||||
*
|
||||
* @throws HibernateException Indicates a problem checking the transaction status.
|
||||
*/
|
||||
public boolean isActive();
|
||||
|
||||
/**
|
||||
* Is Hibernate participating in the underlying transaction?
|
||||
* <p/>
|
||||
* Generally speaking this will be the same as {@link #isActive()}.
|
||||
*
|
||||
* @return {@code true} if Hibernate is known to be participating in the underlying transaction; {@code false}
|
||||
* otherwise.
|
||||
*/
|
||||
public boolean isParticipating();
|
||||
|
||||
/**
|
||||
* Was this transaction committed?
|
||||
* <p/>
|
||||
* Answers on a best effort basis. For example, in the case of JDBC based transactions we cannot know that a
|
||||
* transaction was committed when the commit was performed directly through the JDBC {@link java.sql.Connection},
|
||||
* only when the commit was done from this.
|
||||
*
|
||||
* @return {@code true} if the transaction is rolled back; {@code false} otherwise.
|
||||
*
|
||||
* @throws HibernateException Indicates a problem checking the transaction status.
|
||||
*/
|
||||
@SuppressWarnings( {"UnusedDeclaration"})
|
||||
public boolean wasCommitted();
|
||||
|
||||
/**
|
||||
* Was this transaction rolled back or set to rollback only?
|
||||
* <p/>
|
||||
* Answers on a best effort basis. For example, in the case of JDBC based transactions we cannot know that a
|
||||
* transaction was rolled back when rollback was performed directly through the JDBC {@link java.sql.Connection},
|
||||
* only when it was rolled back from here.
|
||||
*
|
||||
* @return {@literal true} if the transaction is rolled back; {@literal false} otherwise.
|
||||
*
|
||||
* @throws HibernateException Indicates a problem checking the transaction status.
|
||||
*/
|
||||
@SuppressWarnings( {"UnusedDeclaration"})
|
||||
public boolean wasRolledBack();
|
||||
public TransactionStatus getStatus();
|
||||
|
||||
/**
|
||||
* Register a user synchronization callback for this transaction.
|
||||
|
@ -168,4 +113,10 @@ public interface Transaction {
|
|||
* @return The timeout, in seconds.
|
||||
*/
|
||||
public int getTimeout();
|
||||
|
||||
/**
|
||||
* Make a best effort to mark the underlying transaction for rollback only.
|
||||
*/
|
||||
public void markRollbackOnly();
|
||||
|
||||
}
|
||||
|
|
|
@ -60,12 +60,12 @@ import org.hibernate.engine.config.internal.ConfigurationServiceImpl;
|
|||
import org.hibernate.engine.config.spi.ConfigurationService;
|
||||
import org.hibernate.engine.jdbc.env.spi.ExtractedDatabaseMetaData;
|
||||
import org.hibernate.engine.jdbc.spi.JdbcServices;
|
||||
import org.hibernate.engine.transaction.spi.TransactionFactory;
|
||||
import org.hibernate.hql.spi.id.MultiTableBulkIdStrategy;
|
||||
import org.hibernate.internal.SessionFactoryImpl;
|
||||
import org.hibernate.internal.util.config.ConfigurationHelper;
|
||||
import org.hibernate.loader.BatchFetchStyle;
|
||||
import org.hibernate.proxy.EntityNotFoundDelegate;
|
||||
import org.hibernate.resource.transaction.TransactionCoordinatorBuilder;
|
||||
import org.hibernate.service.spi.ServiceRegistryImplementor;
|
||||
import org.hibernate.tuple.entity.EntityTuplizer;
|
||||
import org.hibernate.tuple.entity.EntityTuplizerFactory;
|
||||
|
@ -113,6 +113,7 @@ import static org.hibernate.cfg.AvailableSettings.USE_SQL_COMMENTS;
|
|||
import static org.hibernate.cfg.AvailableSettings.USE_STRUCTURED_CACHE;
|
||||
import static org.hibernate.cfg.AvailableSettings.WRAP_RESULT_SETS;
|
||||
import static org.hibernate.engine.config.spi.StandardConverters.BOOLEAN;
|
||||
import static org.hibernate.cfg.AvailableSettings.PREFER_USER_TRANSACTION;
|
||||
|
||||
/**
|
||||
* @author Gail Badner
|
||||
|
@ -532,6 +533,7 @@ public class SessionFactoryBuilderImpl implements SessionFactoryBuilderImplement
|
|||
private boolean wrapResultSetsEnabled;
|
||||
|
||||
private Map<String, SQLFunction> sqlFunctions;
|
||||
private boolean preferUserTransaction;
|
||||
|
||||
public SessionFactoryOptionsStateStandardImpl(StandardServiceRegistry serviceRegistry) {
|
||||
this.serviceRegistry = serviceRegistry;
|
||||
|
@ -683,13 +685,16 @@ public class SessionFactoryBuilderImpl implements SessionFactoryBuilderImplement
|
|||
|
||||
final String releaseModeName = ConfigurationHelper.getString( RELEASE_CONNECTIONS, configurationSettings, "auto" );
|
||||
if ( "auto".equals( releaseModeName ) ) {
|
||||
this.connectionReleaseMode = serviceRegistry.getService( TransactionFactory.class ).getDefaultReleaseMode();
|
||||
this.connectionReleaseMode = serviceRegistry.getService( TransactionCoordinatorBuilder.class )
|
||||
.getDefaultConnectionReleaseMode();
|
||||
}
|
||||
else {
|
||||
connectionReleaseMode = ConnectionReleaseMode.parse( releaseModeName );
|
||||
}
|
||||
|
||||
this.commentsEnabled = ConfigurationHelper.getBoolean( USE_SQL_COMMENTS, configurationSettings );
|
||||
|
||||
this.preferUserTransaction = ConfigurationHelper.getBoolean( PREFER_USER_TRANSACTION, configurationSettings, false );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -947,6 +952,10 @@ public class SessionFactoryBuilderImpl implements SessionFactoryBuilderImplement
|
|||
return sqlFunctions == null ? Collections.<String, SQLFunction>emptyMap() : sqlFunctions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPreferUserTransaction() {
|
||||
return this.preferUserTransaction;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -74,9 +74,6 @@ import org.hibernate.dialect.SybaseASE15Dialect;
|
|||
import org.hibernate.dialect.SybaseAnywhereDialect;
|
||||
import org.hibernate.dialect.TeradataDialect;
|
||||
import org.hibernate.dialect.TimesTenDialect;
|
||||
import org.hibernate.engine.transaction.internal.jdbc.JdbcTransactionFactory;
|
||||
import org.hibernate.engine.transaction.internal.jta.CMTTransactionFactory;
|
||||
import org.hibernate.engine.transaction.internal.jta.JtaTransactionFactory;
|
||||
import org.hibernate.engine.transaction.jta.platform.internal.BitronixJtaPlatform;
|
||||
import org.hibernate.engine.transaction.jta.platform.internal.BorlandEnterpriseServerJtaPlatform;
|
||||
import org.hibernate.engine.transaction.jta.platform.internal.JBossAppServerJtaPlatform;
|
||||
|
@ -92,7 +89,6 @@ import org.hibernate.engine.transaction.jta.platform.internal.WebSphereExtendedJ
|
|||
import org.hibernate.engine.transaction.jta.platform.internal.WebSphereJtaPlatform;
|
||||
import org.hibernate.engine.transaction.jta.platform.internal.WeblogicJtaPlatform;
|
||||
import org.hibernate.engine.transaction.jta.platform.spi.JtaPlatform;
|
||||
import org.hibernate.engine.transaction.spi.TransactionFactory;
|
||||
import org.hibernate.event.internal.EntityCopyAllowedLoggedObserver;
|
||||
import org.hibernate.event.internal.EntityCopyAllowedObserver;
|
||||
import org.hibernate.event.internal.EntityCopyNotAllowedObserver;
|
||||
|
@ -165,7 +161,7 @@ public class StrategySelectorBuilder {
|
|||
// build the baseline...
|
||||
addDialects( strategySelector );
|
||||
addJtaPlatforms( strategySelector );
|
||||
addTransactionFactories( strategySelector );
|
||||
// addTransactionFactories( strategySelector );
|
||||
addMultiTableBulkIdStrategies( strategySelector );
|
||||
addEntityCopyObserverStrategies( strategySelector );
|
||||
|
||||
|
@ -355,16 +351,16 @@ public class StrategySelectorBuilder {
|
|||
}
|
||||
}
|
||||
|
||||
private void addTransactionFactories(StrategySelectorImpl strategySelector) {
|
||||
strategySelector.registerStrategyImplementor( TransactionFactory.class, JdbcTransactionFactory.SHORT_NAME, JdbcTransactionFactory.class );
|
||||
strategySelector.registerStrategyImplementor( TransactionFactory.class, "org.hibernate.transaction.JDBCTransactionFactory", JdbcTransactionFactory.class );
|
||||
|
||||
strategySelector.registerStrategyImplementor( TransactionFactory.class, JtaTransactionFactory.SHORT_NAME, JtaTransactionFactory.class );
|
||||
strategySelector.registerStrategyImplementor( TransactionFactory.class, "org.hibernate.transaction.JTATransactionFactory", JtaTransactionFactory.class );
|
||||
|
||||
strategySelector.registerStrategyImplementor( TransactionFactory.class, CMTTransactionFactory.SHORT_NAME, CMTTransactionFactory.class );
|
||||
strategySelector.registerStrategyImplementor( TransactionFactory.class, "org.hibernate.transaction.CMTTransactionFactory", CMTTransactionFactory.class );
|
||||
}
|
||||
// private void addTransactionFactories(StrategySelectorImpl strategySelector) {
|
||||
// strategySelector.registerStrategyImplementor( TransactionFactory.class, JdbcTransactionFactory.SHORT_NAME, JdbcTransactionFactory.class );
|
||||
// strategySelector.registerStrategyImplementor( TransactionFactory.class, "org.hibernate.transaction.JDBCTransactionFactory", JdbcTransactionFactory.class );
|
||||
//
|
||||
// strategySelector.registerStrategyImplementor( TransactionFactory.class, JtaTransactionFactory.SHORT_NAME, JtaTransactionFactory.class );
|
||||
// strategySelector.registerStrategyImplementor( TransactionFactory.class, "org.hibernate.transaction.JTATransactionFactory", JtaTransactionFactory.class );
|
||||
//
|
||||
// strategySelector.registerStrategyImplementor( TransactionFactory.class, CMTTransactionFactory.SHORT_NAME, CMTTransactionFactory.class );
|
||||
// strategySelector.registerStrategyImplementor( TransactionFactory.class, "org.hibernate.transaction.CMTTransactionFactory", CMTTransactionFactory.class );
|
||||
// }
|
||||
|
||||
private void addMultiTableBulkIdStrategies(StrategySelectorImpl strategySelector) {
|
||||
strategySelector.registerStrategyImplementor(
|
||||
|
|
|
@ -183,4 +183,6 @@ public interface SessionFactoryOptions {
|
|||
public Map<String, SQLFunction> getCustomSqlFunctionMap();
|
||||
|
||||
void setCheckNullability(boolean enabled);
|
||||
|
||||
public boolean isPreferUserTransaction();
|
||||
}
|
||||
|
|
|
@ -282,10 +282,10 @@ public interface AvailableSettings {
|
|||
String CURRENT_SESSION_CONTEXT_CLASS = "hibernate.current_session_context_class";
|
||||
|
||||
/**
|
||||
* Names the implementation of {@link org.hibernate.engine.transaction.spi.TransactionFactory} to use for
|
||||
* creating {@link org.hibernate.Transaction} instances
|
||||
* Names the implementation of {@link org.hibernate.resource.transaction.TransactionCoordinatorBuilder} to use for
|
||||
* creating {@link org.hibernate.resource.transaction.TransactionCoordinator} instances
|
||||
*/
|
||||
String TRANSACTION_STRATEGY = "hibernate.transaction.factory_class";
|
||||
String TRANSACTION_COORDINATOR_STRATEGY = "hibernate.transaction.coordinator_class";
|
||||
|
||||
/**
|
||||
* Names the {@link org.hibernate.engine.transaction.jta.platform.spi.JtaPlatform} implementation to use for integrating
|
||||
|
@ -807,4 +807,13 @@ public interface AvailableSettings {
|
|||
* annotations (combined with {@code orm.xml} mappings).
|
||||
*/
|
||||
String ARTIFACT_PROCESSING_ORDER = "hibernate.mapping.precedence";
|
||||
|
||||
/**
|
||||
* Used to specify if using {@link javax.transaction.UserTransaction} class to use for JTA transaction management.
|
||||
*
|
||||
* Default is <code>false</code>
|
||||
*
|
||||
* @since 5.0
|
||||
*/
|
||||
String PREFER_USER_TRANSACTION = "hibernate.jta.prefer_user_transaction";
|
||||
}
|
||||
|
|
|
@ -329,4 +329,8 @@ public final class Settings {
|
|||
// ugh, used by org.hibernate.cfg.beanvalidation.TypeSafeActivator as part of the BV integrator
|
||||
sessionFactoryOptions.setCheckNullability( enabled );
|
||||
}
|
||||
|
||||
public boolean isPreferUserTransaction() {
|
||||
return sessionFactoryOptions.isPreferUserTransaction();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -242,10 +242,7 @@ public abstract class AbstractPersistentCollection implements Serializable, Pers
|
|||
}
|
||||
|
||||
if ( isTempSession ) {
|
||||
isJTA = session.getTransactionCoordinator()
|
||||
.getTransactionContext().getTransactionEnvironment()
|
||||
.getTransactionFactory()
|
||||
.compatibleWithJtaSynchronization();
|
||||
isJTA = session.getTransactionCoordinator().getTransactionCoordinatorBuilder().isJta();
|
||||
|
||||
if ( !isJTA ) {
|
||||
// Explicitly handle the transactions only if we're not in
|
||||
|
|
|
@ -43,9 +43,9 @@ import org.hibernate.context.spi.AbstractCurrentSessionContext;
|
|||
import org.hibernate.engine.jdbc.LobCreationContext;
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.engine.spi.SessionImplementor;
|
||||
import org.hibernate.engine.transaction.spi.TransactionContext;
|
||||
import org.hibernate.event.spi.EventSource;
|
||||
import org.hibernate.internal.CoreMessageLogger;
|
||||
import org.hibernate.resource.transaction.spi.TransactionStatus;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
|
@ -81,7 +81,6 @@ public class ThreadLocalSessionContext extends AbstractCurrentSessionContext {
|
|||
Session.class,
|
||||
SessionImplementor.class,
|
||||
EventSource.class,
|
||||
TransactionContext.class,
|
||||
LobCreationContext.class
|
||||
};
|
||||
|
||||
|
@ -220,7 +219,7 @@ public class ThreadLocalSessionContext extends AbstractCurrentSessionContext {
|
|||
if ( orphan != null ) {
|
||||
LOG.alreadySessionBound();
|
||||
try {
|
||||
if ( orphan.getTransaction() != null && orphan.getTransaction().isActive() ) {
|
||||
if ( orphan.getTransaction() != null && orphan.getTransaction().getStatus() == TransactionStatus.ACTIVE ) {
|
||||
try {
|
||||
orphan.getTransaction().rollback();
|
||||
}
|
||||
|
@ -333,7 +332,7 @@ public class ThreadLocalSessionContext extends AbstractCurrentSessionContext {
|
|||
// but we capture that there simply to doAfterTransactionCompletion the unbind...
|
||||
LOG.tracef( "Allowing invocation [%s] to proceed to real (closed) session", methodName );
|
||||
}
|
||||
else if ( !realSession.getTransaction().isActive() ) {
|
||||
else if ( realSession.getTransaction().getStatus() != TransactionStatus.ACTIVE ) {
|
||||
// limit the methods available if no transaction is active
|
||||
if ( "beginTransaction".equals( methodName )
|
||||
|| "getTransaction".equals( methodName )
|
||||
|
|
|
@ -73,7 +73,7 @@ public class PessimisticReadSelectLockingStrategy extends AbstractSelectLockingS
|
|||
final SessionFactoryImplementor factory = session.getFactory();
|
||||
try {
|
||||
try {
|
||||
final PreparedStatement st = session.getTransactionCoordinator().getJdbcCoordinator().getStatementPreparer().prepareStatement( sql );
|
||||
final PreparedStatement st = session.getJdbcCoordinator().getStatementPreparer().prepareStatement( sql );
|
||||
try {
|
||||
getLockable().getIdentifierType().nullSafeSet( st, id, 1, session );
|
||||
if ( getLockable().isVersioned() ) {
|
||||
|
@ -85,7 +85,7 @@ public class PessimisticReadSelectLockingStrategy extends AbstractSelectLockingS
|
|||
);
|
||||
}
|
||||
|
||||
final ResultSet rs = session.getTransactionCoordinator().getJdbcCoordinator().getResultSetReturn().extract( st );
|
||||
final ResultSet rs = session.getJdbcCoordinator().getResultSetReturn().extract( st );
|
||||
try {
|
||||
if ( !rs.next() ) {
|
||||
if ( factory.getStatistics().isStatisticsEnabled() ) {
|
||||
|
@ -96,11 +96,12 @@ public class PessimisticReadSelectLockingStrategy extends AbstractSelectLockingS
|
|||
}
|
||||
}
|
||||
finally {
|
||||
session.getTransactionCoordinator().getJdbcCoordinator().release( rs, st );
|
||||
session.getJdbcCoordinator().getResourceRegistry().release( rs, st );
|
||||
}
|
||||
}
|
||||
finally {
|
||||
session.getTransactionCoordinator().getJdbcCoordinator().release( st );
|
||||
session.getJdbcCoordinator().getResourceRegistry().release( st );
|
||||
session.getJdbcCoordinator().afterStatementExecution();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -92,7 +92,7 @@ public class PessimisticReadUpdateLockingStrategy implements LockingStrategy {
|
|||
final SessionFactoryImplementor factory = session.getFactory();
|
||||
try {
|
||||
try {
|
||||
final PreparedStatement st = session.getTransactionCoordinator().getJdbcCoordinator().getStatementPreparer().prepareStatement( sql );
|
||||
final PreparedStatement st = session.getJdbcCoordinator().getStatementPreparer().prepareStatement( sql );
|
||||
try {
|
||||
lockable.getVersionType().nullSafeSet( st, version, 1, session );
|
||||
int offset = 2;
|
||||
|
@ -104,7 +104,7 @@ public class PessimisticReadUpdateLockingStrategy implements LockingStrategy {
|
|||
lockable.getVersionType().nullSafeSet( st, version, offset, session );
|
||||
}
|
||||
|
||||
final int affected = session.getTransactionCoordinator().getJdbcCoordinator().getResultSetReturn().executeUpdate( st );
|
||||
final int affected = session.getJdbcCoordinator().getResultSetReturn().executeUpdate( st );
|
||||
// todo: should this instead check for exactly one row modified?
|
||||
if ( affected < 0 ) {
|
||||
if (factory.getStatistics().isStatisticsEnabled()) {
|
||||
|
@ -115,7 +115,8 @@ public class PessimisticReadUpdateLockingStrategy implements LockingStrategy {
|
|||
|
||||
}
|
||||
finally {
|
||||
session.getTransactionCoordinator().getJdbcCoordinator().release( st );
|
||||
session.getJdbcCoordinator().getResourceRegistry().release( st );
|
||||
session.getJdbcCoordinator().afterStatementExecution();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -72,7 +72,7 @@ public class PessimisticWriteSelectLockingStrategy extends AbstractSelectLocking
|
|||
final SessionFactoryImplementor factory = session.getFactory();
|
||||
try {
|
||||
try {
|
||||
final PreparedStatement st = session.getTransactionCoordinator().getJdbcCoordinator().getStatementPreparer().prepareStatement( sql );
|
||||
final PreparedStatement st = session.getJdbcCoordinator().getStatementPreparer().prepareStatement( sql );
|
||||
try {
|
||||
getLockable().getIdentifierType().nullSafeSet( st, id, 1, session );
|
||||
if ( getLockable().isVersioned() ) {
|
||||
|
@ -84,7 +84,7 @@ public class PessimisticWriteSelectLockingStrategy extends AbstractSelectLocking
|
|||
);
|
||||
}
|
||||
|
||||
final ResultSet rs = session.getTransactionCoordinator().getJdbcCoordinator().getResultSetReturn().extract( st );
|
||||
final ResultSet rs = session.getJdbcCoordinator().getResultSetReturn().extract( st );
|
||||
try {
|
||||
if ( !rs.next() ) {
|
||||
if ( factory.getStatistics().isStatisticsEnabled() ) {
|
||||
|
@ -95,11 +95,12 @@ public class PessimisticWriteSelectLockingStrategy extends AbstractSelectLocking
|
|||
}
|
||||
}
|
||||
finally {
|
||||
session.getTransactionCoordinator().getJdbcCoordinator().release( rs, st );
|
||||
session.getJdbcCoordinator().getResourceRegistry().release( rs, st );
|
||||
}
|
||||
}
|
||||
finally {
|
||||
session.getTransactionCoordinator().getJdbcCoordinator().release( st );
|
||||
session.getJdbcCoordinator().getResourceRegistry().release( st );
|
||||
session.getJdbcCoordinator().afterStatementExecution();
|
||||
}
|
||||
}
|
||||
catch ( SQLException e ) {
|
||||
|
|
|
@ -91,7 +91,7 @@ public class PessimisticWriteUpdateLockingStrategy implements LockingStrategy {
|
|||
final SessionFactoryImplementor factory = session.getFactory();
|
||||
try {
|
||||
try {
|
||||
final PreparedStatement st = session.getTransactionCoordinator().getJdbcCoordinator().getStatementPreparer().prepareStatement( sql );
|
||||
final PreparedStatement st = session.getJdbcCoordinator().getStatementPreparer().prepareStatement( sql );
|
||||
try {
|
||||
lockable.getVersionType().nullSafeSet( st, version, 1, session );
|
||||
int offset = 2;
|
||||
|
@ -103,7 +103,7 @@ public class PessimisticWriteUpdateLockingStrategy implements LockingStrategy {
|
|||
lockable.getVersionType().nullSafeSet( st, version, offset, session );
|
||||
}
|
||||
|
||||
final int affected = session.getTransactionCoordinator().getJdbcCoordinator().getResultSetReturn().executeUpdate( st );
|
||||
final int affected = session.getJdbcCoordinator().getResultSetReturn().executeUpdate( st );
|
||||
// todo: should this instead check for exactly one row modified?
|
||||
if ( affected < 0 ) {
|
||||
if (factory.getStatistics().isStatisticsEnabled()) {
|
||||
|
@ -114,7 +114,8 @@ public class PessimisticWriteUpdateLockingStrategy implements LockingStrategy {
|
|||
|
||||
}
|
||||
finally {
|
||||
session.getTransactionCoordinator().getJdbcCoordinator().release( st );
|
||||
session.getJdbcCoordinator().getResourceRegistry().release( st );
|
||||
session.getJdbcCoordinator().afterStatementExecution();
|
||||
}
|
||||
}
|
||||
catch ( SQLException e ) {
|
||||
|
|
|
@ -71,7 +71,7 @@ public class SelectLockingStrategy extends AbstractSelectLockingStrategy {
|
|||
final String sql = determineSql( timeout );
|
||||
final SessionFactoryImplementor factory = session.getFactory();
|
||||
try {
|
||||
final PreparedStatement st = session.getTransactionCoordinator().getJdbcCoordinator().getStatementPreparer().prepareStatement( sql );
|
||||
final PreparedStatement st = session.getJdbcCoordinator().getStatementPreparer().prepareStatement( sql );
|
||||
try {
|
||||
getLockable().getIdentifierType().nullSafeSet( st, id, 1, session );
|
||||
if ( getLockable().isVersioned() ) {
|
||||
|
@ -83,7 +83,7 @@ public class SelectLockingStrategy extends AbstractSelectLockingStrategy {
|
|||
);
|
||||
}
|
||||
|
||||
final ResultSet rs = session.getTransactionCoordinator().getJdbcCoordinator().getResultSetReturn().extract( st );
|
||||
final ResultSet rs = session.getJdbcCoordinator().getResultSetReturn().extract( st );
|
||||
try {
|
||||
if ( !rs.next() ) {
|
||||
if ( factory.getStatistics().isStatisticsEnabled() ) {
|
||||
|
@ -94,11 +94,12 @@ public class SelectLockingStrategy extends AbstractSelectLockingStrategy {
|
|||
}
|
||||
}
|
||||
finally {
|
||||
session.getTransactionCoordinator().getJdbcCoordinator().release( rs, st );
|
||||
session.getJdbcCoordinator().getResourceRegistry().release( rs, st );
|
||||
}
|
||||
}
|
||||
finally {
|
||||
session.getTransactionCoordinator().getJdbcCoordinator().release( st );
|
||||
session.getJdbcCoordinator().getResourceRegistry().release( st );
|
||||
session.getJdbcCoordinator().afterStatementExecution();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -94,7 +94,7 @@ public class UpdateLockingStrategy implements LockingStrategy {
|
|||
// todo : should we additionally check the current isolation mode explicitly?
|
||||
final SessionFactoryImplementor factory = session.getFactory();
|
||||
try {
|
||||
final PreparedStatement st = session.getTransactionCoordinator().getJdbcCoordinator().getStatementPreparer().prepareStatement( sql );
|
||||
final PreparedStatement st = session.getJdbcCoordinator().getStatementPreparer().prepareStatement( sql );
|
||||
try {
|
||||
lockable.getVersionType().nullSafeSet( st, version, 1, session );
|
||||
int offset = 2;
|
||||
|
@ -106,7 +106,7 @@ public class UpdateLockingStrategy implements LockingStrategy {
|
|||
lockable.getVersionType().nullSafeSet( st, version, offset, session );
|
||||
}
|
||||
|
||||
final int affected = session.getTransactionCoordinator().getJdbcCoordinator().getResultSetReturn().executeUpdate( st );
|
||||
final int affected = session.getJdbcCoordinator().getResultSetReturn().executeUpdate( st );
|
||||
if ( affected < 0 ) {
|
||||
if (factory.getStatistics().isStatisticsEnabled()) {
|
||||
factory.getStatisticsImplementor().optimisticFailure( lockable.getEntityName() );
|
||||
|
@ -116,7 +116,8 @@ public class UpdateLockingStrategy implements LockingStrategy {
|
|||
|
||||
}
|
||||
finally {
|
||||
session.getTransactionCoordinator().getJdbcCoordinator().release( st );
|
||||
session.getJdbcCoordinator().getResourceRegistry().release( st );
|
||||
session.getJdbcCoordinator().afterStatementExecution();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -28,6 +28,8 @@ import java.sql.SQLException;
|
|||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
import org.hibernate.engine.jdbc.batch.spi.Batch;
|
||||
import org.hibernate.engine.jdbc.batch.spi.BatchKey;
|
||||
import org.hibernate.engine.jdbc.batch.spi.BatchObserver;
|
||||
|
@ -35,11 +37,8 @@ import org.hibernate.engine.jdbc.spi.JdbcCoordinator;
|
|||
import org.hibernate.engine.jdbc.spi.JdbcServices;
|
||||
import org.hibernate.engine.jdbc.spi.SqlExceptionHelper;
|
||||
import org.hibernate.engine.jdbc.spi.SqlStatementLogger;
|
||||
import org.hibernate.engine.transaction.spi.TransactionContext;
|
||||
import org.hibernate.internal.CoreMessageLogger;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
/**
|
||||
* Convenience base class for implementers of the Batch interface.
|
||||
*
|
||||
|
@ -55,7 +54,6 @@ public abstract class AbstractBatchImpl implements Batch {
|
|||
private final BatchKey key;
|
||||
private final JdbcCoordinator jdbcCoordinator;
|
||||
|
||||
private final TransactionContext transactionContext;
|
||||
private final SqlStatementLogger sqlStatementLogger;
|
||||
private final SqlExceptionHelper sqlExceptionHelper;
|
||||
|
||||
|
@ -72,24 +70,27 @@ public abstract class AbstractBatchImpl implements Batch {
|
|||
this.key = key;
|
||||
this.jdbcCoordinator = jdbcCoordinator;
|
||||
|
||||
this.transactionContext = jdbcCoordinator.getTransactionCoordinator().getTransactionContext();
|
||||
final JdbcServices jdbcServices = transactionContext.getTransactionEnvironment().getJdbcServices();
|
||||
final JdbcServices jdbcServices = jdbcCoordinator.getJdbcSessionOwner()
|
||||
.getJdbcSessionContext()
|
||||
.getServiceRegistry()
|
||||
.getService( JdbcServices.class );
|
||||
|
||||
this.sqlStatementLogger = jdbcServices.getSqlStatementLogger();
|
||||
this.sqlExceptionHelper = jdbcServices.getSqlExceptionHelper();
|
||||
}
|
||||
|
||||
protected JdbcCoordinator getJdbcCoordinator(){
|
||||
return this.jdbcCoordinator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform batch execution.
|
||||
* Perform batch execution..
|
||||
* <p/>
|
||||
* This is called from the explicit {@link #execute() execution}, but may also be called from elsewhere
|
||||
* depending on the exact implementation.
|
||||
*/
|
||||
protected abstract void doExecuteBatch();
|
||||
|
||||
public TransactionContext transactionContext() {
|
||||
return transactionContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience access to the SQLException helper.
|
||||
*
|
||||
|
@ -170,7 +171,8 @@ public abstract class AbstractBatchImpl implements Batch {
|
|||
protected void releaseStatements() {
|
||||
for ( PreparedStatement statement : getStatements().values() ) {
|
||||
clearBatch( statement );
|
||||
jdbcCoordinator.release( statement );
|
||||
jdbcCoordinator.getResourceRegistry().release( statement );
|
||||
jdbcCoordinator.afterStatementExecution();
|
||||
}
|
||||
getStatements().clear();
|
||||
}
|
||||
|
|
|
@ -123,11 +123,11 @@ public class BatchingBatch extends AbstractBatchImpl {
|
|||
final PreparedStatement statement = entry.getValue();
|
||||
final int[] rowCounts;
|
||||
try {
|
||||
transactionContext().startBatchExecution();
|
||||
getJdbcCoordinator().getJdbcSessionOwner().getJdbcSessionContext().getObserver().jdbcExecuteBatchStart();
|
||||
rowCounts = statement.executeBatch();
|
||||
}
|
||||
finally {
|
||||
transactionContext().endBatchExecution();
|
||||
getJdbcCoordinator().getJdbcSessionOwner().getJdbcSessionContext().getObserver().jdbcExecuteBatchEnd();
|
||||
}
|
||||
checkRowCounts( rowCounts, statement );
|
||||
}
|
||||
|
|
|
@ -61,7 +61,8 @@ public class NonBatchingBatch extends AbstractBatchImpl {
|
|||
final PreparedStatement statement = entry.getValue();
|
||||
final int rowCount = jdbcCoordinator.getResultSetReturn().executeUpdate( statement );
|
||||
getKey().getExpectation().verifyOutcome( rowCount, statement, 0 );
|
||||
jdbcCoordinator.release( statement );
|
||||
jdbcCoordinator.getResourceRegistry().release( statement );
|
||||
jdbcCoordinator.afterStatementExecution();
|
||||
}
|
||||
catch ( SQLException e ) {
|
||||
abortBatch();
|
||||
|
|
|
@ -36,29 +36,32 @@ import java.util.HashSet;
|
|||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
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.spi.InvalidatableWrapper;
|
||||
import org.hibernate.engine.jdbc.spi.JdbcCoordinator;
|
||||
import org.hibernate.engine.jdbc.spi.JdbcServices;
|
||||
import org.hibernate.engine.jdbc.spi.JdbcWrapper;
|
||||
import org.hibernate.engine.jdbc.spi.LogicalConnectionImplementor;
|
||||
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.engine.transaction.internal.TransactionCoordinatorImpl;
|
||||
import org.hibernate.engine.transaction.spi.TransactionContext;
|
||||
import org.hibernate.engine.transaction.spi.TransactionCoordinator;
|
||||
import org.hibernate.engine.transaction.spi.TransactionEnvironment;
|
||||
import org.hibernate.internal.CoreMessageLogger;
|
||||
import org.hibernate.jdbc.WorkExecutor;
|
||||
import org.hibernate.jdbc.WorkExecutorVisitable;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
import org.hibernate.resource.jdbc.ResourceRegistry;
|
||||
import org.hibernate.resource.jdbc.internal.LogicalConnectionManagedImpl;
|
||||
import org.hibernate.resource.jdbc.internal.LogicalConnectionProvidedImpl;
|
||||
import org.hibernate.resource.jdbc.spi.JdbcSessionOwner;
|
||||
import org.hibernate.resource.jdbc.spi.LogicalConnectionImplementor;
|
||||
import org.hibernate.resource.transaction.backend.store.spi.DataStoreTransaction;
|
||||
|
||||
/**
|
||||
* Standard Hibernate implementation of {@link JdbcCoordinator}
|
||||
|
@ -75,8 +78,11 @@ public class JdbcCoordinatorImpl implements JdbcCoordinator {
|
|||
JdbcCoordinatorImpl.class.getName()
|
||||
);
|
||||
|
||||
private transient TransactionCoordinator transactionCoordinator;
|
||||
private final transient LogicalConnectionImpl logicalConnection;
|
||||
private boolean closed;
|
||||
|
||||
private transient LogicalConnectionImplementor logicalConnection;
|
||||
private transient JdbcSessionOwner owner;
|
||||
private final ConnectionReleaseMode connectionReleaseMode;
|
||||
|
||||
private transient Batch currentBatch;
|
||||
|
||||
|
@ -92,9 +98,11 @@ public class JdbcCoordinatorImpl implements JdbcCoordinator {
|
|||
|
||||
private final HashMap<Statement,Set<ResultSet>> xref = new HashMap<Statement,Set<ResultSet>>();
|
||||
private final Set<ResultSet> unassociatedResultSets = new HashSet<ResultSet>();
|
||||
private final transient SqlExceptionHelper exceptionHelper;
|
||||
private transient SqlExceptionHelper exceptionHelper;
|
||||
|
||||
private Statement lastQuery;
|
||||
private final boolean isUserSuppliedConnection;
|
||||
|
||||
|
||||
/**
|
||||
* If true, manually (and temporarily) circumvent aggressive release processing.
|
||||
|
@ -105,43 +113,47 @@ public class JdbcCoordinatorImpl implements JdbcCoordinator {
|
|||
* Constructs a JdbcCoordinatorImpl
|
||||
*
|
||||
* @param userSuppliedConnection The user supplied connection (may be null)
|
||||
* @param transactionCoordinator The transaction coordinator
|
||||
*/
|
||||
public JdbcCoordinatorImpl(
|
||||
Connection userSuppliedConnection,
|
||||
TransactionCoordinator transactionCoordinator) {
|
||||
this.transactionCoordinator = transactionCoordinator;
|
||||
this.logicalConnection = new LogicalConnectionImpl(
|
||||
userSuppliedConnection,
|
||||
transactionCoordinator.getTransactionContext().getConnectionReleaseMode(),
|
||||
transactionCoordinator.getTransactionContext().getTransactionEnvironment().getJdbcServices(),
|
||||
transactionCoordinator.getTransactionContext().getJdbcConnectionAccess()
|
||||
JdbcSessionOwner owner) {
|
||||
if ( userSuppliedConnection != null ) {
|
||||
this.logicalConnection = new LogicalConnectionProvidedImpl( userSuppliedConnection );
|
||||
this.isUserSuppliedConnection = true;
|
||||
}
|
||||
else {
|
||||
this.logicalConnection = new LogicalConnectionManagedImpl(
|
||||
owner.getJdbcConnectionAccess(),
|
||||
owner.getJdbcSessionContext()
|
||||
);
|
||||
this.isUserSuppliedConnection = false;
|
||||
}
|
||||
this.connectionReleaseMode = determineConnectionReleaseMode(
|
||||
owner.getJdbcConnectionAccess(),
|
||||
isUserSuppliedConnection,
|
||||
owner.getJdbcSessionContext()
|
||||
.getConnectionReleaseMode()
|
||||
);
|
||||
this.exceptionHelper = logicalConnection.getJdbcServices().getSqlExceptionHelper();
|
||||
this.owner = owner;
|
||||
this.exceptionHelper = owner.getJdbcSessionContext()
|
||||
.getServiceRegistry()
|
||||
.getService( JdbcServices.class )
|
||||
.getSqlExceptionHelper();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a JdbcCoordinatorImpl
|
||||
*
|
||||
* @param logicalConnection The logical JDBC connection
|
||||
* @param transactionCoordinator The transaction coordinator
|
||||
*/
|
||||
public JdbcCoordinatorImpl(
|
||||
LogicalConnectionImpl logicalConnection,
|
||||
TransactionCoordinator transactionCoordinator) {
|
||||
this.transactionCoordinator = transactionCoordinator;
|
||||
private JdbcCoordinatorImpl(
|
||||
LogicalConnectionImplementor logicalConnection,
|
||||
boolean isUserSuppliedConnection,
|
||||
ConnectionReleaseMode connectionReleaseMode,
|
||||
JdbcSessionOwner owner) {
|
||||
this.logicalConnection = logicalConnection;
|
||||
this.exceptionHelper = logicalConnection.getJdbcServices().getSqlExceptionHelper();
|
||||
}
|
||||
|
||||
private JdbcCoordinatorImpl(LogicalConnectionImpl logicalConnection) {
|
||||
this.logicalConnection = logicalConnection;
|
||||
this.exceptionHelper = logicalConnection.getJdbcServices().getSqlExceptionHelper();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TransactionCoordinator getTransactionCoordinator() {
|
||||
return transactionCoordinator;
|
||||
this.isUserSuppliedConnection = isUserSuppliedConnection;
|
||||
this.connectionReleaseMode = connectionReleaseMode;
|
||||
this.owner = owner;
|
||||
this.exceptionHelper = owner.getJdbcSessionContext()
|
||||
.getServiceRegistry()
|
||||
.getService( JdbcServices.class )
|
||||
.getSqlExceptionHelper();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -149,12 +161,8 @@ public class JdbcCoordinatorImpl implements JdbcCoordinator {
|
|||
return logicalConnection;
|
||||
}
|
||||
|
||||
protected TransactionEnvironment transactionEnvironment() {
|
||||
return getTransactionCoordinator().getTransactionContext().getTransactionEnvironment();
|
||||
}
|
||||
|
||||
protected SessionFactoryImplementor sessionFactory() {
|
||||
return transactionEnvironment().getSessionFactory();
|
||||
return this.owner.getJdbcSessionContext().getSessionFactory();
|
||||
}
|
||||
|
||||
protected BatchBuilder batchBuilder() {
|
||||
|
@ -170,7 +178,6 @@ public class JdbcCoordinatorImpl implements JdbcCoordinator {
|
|||
return exceptionHelper;
|
||||
}
|
||||
|
||||
|
||||
private int flushDepth;
|
||||
|
||||
@Override
|
||||
|
@ -202,6 +209,7 @@ public class JdbcCoordinatorImpl implements JdbcCoordinator {
|
|||
currentBatch.release();
|
||||
}
|
||||
cleanup();
|
||||
closed = true;
|
||||
return logicalConnection.close();
|
||||
}
|
||||
|
||||
|
@ -261,6 +269,11 @@ public class JdbcCoordinatorImpl implements JdbcCoordinator {
|
|||
transactionTimeOutInstant = System.currentTimeMillis() + ( seconds * 1000 );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void flushBeforeTransactionCompletion() {
|
||||
getJdbcSessionOwner().flushBeforeTransactionCompletion();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int determineRemainingTransactionTimeOutPeriod() {
|
||||
if ( transactionTimeOutInstant < 0 ) {
|
||||
|
@ -275,8 +288,8 @@ public class JdbcCoordinatorImpl implements JdbcCoordinator {
|
|||
|
||||
@Override
|
||||
public void afterStatementExecution() {
|
||||
LOG.tracev( "Starting after statement execution processing [{0}]", connectionReleaseMode() );
|
||||
if ( connectionReleaseMode() == ConnectionReleaseMode.AFTER_STATEMENT ) {
|
||||
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;
|
||||
|
@ -285,30 +298,56 @@ public class JdbcCoordinatorImpl implements JdbcCoordinator {
|
|||
LOG.debug( "Skipping aggressive release due to registered resources" );
|
||||
return;
|
||||
}
|
||||
getLogicalConnection().releaseConnection();
|
||||
getLogicalConnection().afterStatement();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterTransaction() {
|
||||
transactionTimeOutInstant = -1;
|
||||
if ( connectionReleaseMode() == ConnectionReleaseMode.AFTER_STATEMENT ||
|
||||
connectionReleaseMode() == ConnectionReleaseMode.AFTER_TRANSACTION ) {
|
||||
if ( hasRegisteredResources() ) {
|
||||
LOG.forcingContainerResourceCleanup();
|
||||
releaseResources();
|
||||
}
|
||||
getLogicalConnection().aggressiveRelease();
|
||||
if ( getConnectionReleaseMode() == ConnectionReleaseMode.AFTER_STATEMENT ||
|
||||
getConnectionReleaseMode() == ConnectionReleaseMode.AFTER_TRANSACTION ) {
|
||||
this.logicalConnection.afterTransaction();
|
||||
}
|
||||
}
|
||||
|
||||
private ConnectionReleaseMode connectionReleaseMode() {
|
||||
return getLogicalConnection().getConnectionReleaseMode();
|
||||
|
||||
private void releaseResources() {
|
||||
getResourceRegistry().releaseResources();
|
||||
}
|
||||
|
||||
private boolean hasRegisteredResources() {
|
||||
return getResourceRegistry().hasRegisteredResources();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceRegistry getResourceRegistry(){
|
||||
return this.logicalConnection.getResourceRegistry();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConnectionReleaseMode getConnectionReleaseMode() {
|
||||
return this.connectionReleaseMode;
|
||||
}
|
||||
|
||||
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().getConnection();
|
||||
final Connection connection = getLogicalConnection().getPhysicalConnection();
|
||||
try {
|
||||
final T result = work.accept( new WorkExecutor<T>(), connection );
|
||||
afterStatementExecution();
|
||||
|
@ -321,65 +360,11 @@ public class JdbcCoordinatorImpl implements JdbcCoordinator {
|
|||
|
||||
@Override
|
||||
public boolean isReadyForSerialization() {
|
||||
return getLogicalConnection().isUserSuppliedConnection()
|
||||
return this.isUserSuppliedConnection
|
||||
? ! getLogicalConnection().isPhysicallyConnected()
|
||||
: ! hasRegisteredResources();
|
||||
}
|
||||
|
||||
/**
|
||||
* JDK serialization hook
|
||||
*
|
||||
* @param oos The stream into which to write our state
|
||||
*
|
||||
* @throws IOException Trouble accessing the stream
|
||||
*/
|
||||
public void serialize(ObjectOutputStream oos) throws IOException {
|
||||
if ( ! isReadyForSerialization() ) {
|
||||
throw new HibernateException( "Cannot serialize Session while connected" );
|
||||
}
|
||||
logicalConnection.serialize( oos );
|
||||
}
|
||||
|
||||
/**
|
||||
* JDK deserialization hook
|
||||
*
|
||||
* @param ois The stream into which to write our state
|
||||
* @param transactionContext The transaction context which owns the JdbcCoordinatorImpl to be deserialized.
|
||||
*
|
||||
* @return The deserialized JdbcCoordinatorImpl
|
||||
*
|
||||
* @throws IOException Trouble accessing the stream
|
||||
* @throws ClassNotFoundException Trouble reading the stream
|
||||
*/
|
||||
public static JdbcCoordinatorImpl deserialize(
|
||||
ObjectInputStream ois,
|
||||
TransactionContext transactionContext) throws IOException, ClassNotFoundException {
|
||||
return new JdbcCoordinatorImpl( LogicalConnectionImpl.deserialize( ois, transactionContext ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback after deserialization from Session is done
|
||||
*
|
||||
* @param transactionCoordinator The transaction coordinator
|
||||
*/
|
||||
public void afterDeserialize(TransactionCoordinatorImpl transactionCoordinator) {
|
||||
this.transactionCoordinator = transactionCoordinator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void register(Statement statement) {
|
||||
LOG.tracev( "Registering statement [{0}]", statement );
|
||||
// Benchmarking has shown this to be a big hotspot. Originally, most usages would call both
|
||||
// #containsKey and #put. Instead, we optimize for the most common path (no previous Statement was
|
||||
// registered) by calling #put only once, but still handling the unlikely conflict and resulting exception.
|
||||
final Set<ResultSet> previousValue = xref.put( statement, EMPTY_RESULTSET );
|
||||
if ( previousValue != null ) {
|
||||
// Put the previous value back to undo the put
|
||||
xref.put( statement, previousValue );
|
||||
throw new HibernateException( "statement already registered with JDBCContainer" );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings({ "unchecked" })
|
||||
public void registerLastQuery(Statement statement) {
|
||||
|
@ -407,92 +392,6 @@ public class JdbcCoordinatorImpl implements JdbcCoordinator {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void release(Statement statement) {
|
||||
LOG.tracev( "Releasing statement [{0}]", statement );
|
||||
final Set<ResultSet> resultSets = xref.get( statement );
|
||||
if ( resultSets != null ) {
|
||||
for ( ResultSet resultSet : resultSets ) {
|
||||
close( resultSet );
|
||||
}
|
||||
resultSets.clear();
|
||||
}
|
||||
xref.remove( statement );
|
||||
close( statement );
|
||||
|
||||
afterStatementExecution();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void register(ResultSet resultSet, Statement statement) {
|
||||
if ( statement == null ) {
|
||||
try {
|
||||
statement = resultSet.getStatement();
|
||||
}
|
||||
catch ( SQLException e ) {
|
||||
throw exceptionHelper.convert( e, "unable to access statement from resultset" );
|
||||
}
|
||||
}
|
||||
if ( statement != null ) {
|
||||
LOG.tracev( "Registering result set [{0}]", resultSet );
|
||||
Set<ResultSet> resultSets = xref.get( statement );
|
||||
if ( resultSets == null ) {
|
||||
LOG.unregisteredStatement();
|
||||
}
|
||||
if ( resultSets == null || resultSets == EMPTY_RESULTSET ) {
|
||||
resultSets = new HashSet<ResultSet>();
|
||||
xref.put( statement, resultSets );
|
||||
}
|
||||
resultSets.add( resultSet );
|
||||
}
|
||||
else {
|
||||
unassociatedResultSets.add( resultSet );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void release(ResultSet resultSet, Statement statement) {
|
||||
LOG.tracev( "Releasing result set [{0}]", resultSet );
|
||||
if ( statement == null ) {
|
||||
try {
|
||||
statement = resultSet.getStatement();
|
||||
}
|
||||
catch ( SQLException e ) {
|
||||
throw exceptionHelper.convert( e, "unable to access statement from resultset" );
|
||||
}
|
||||
}
|
||||
if ( statement != null ) {
|
||||
final Set<ResultSet> resultSets = xref.get( statement );
|
||||
if ( resultSets == null ) {
|
||||
LOG.unregisteredStatement();
|
||||
}
|
||||
else {
|
||||
resultSets.remove( resultSet );
|
||||
if ( resultSets.isEmpty() ) {
|
||||
xref.remove( statement );
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
final boolean removed = unassociatedResultSets.remove( resultSet );
|
||||
if ( !removed ) {
|
||||
LOG.unregisteredResultSetWithoutStatement();
|
||||
}
|
||||
}
|
||||
close( resultSet );
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasRegisteredResources() {
|
||||
return ! xref.isEmpty() || ! unassociatedResultSets.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void releaseResources() {
|
||||
LOG.tracev( "Releasing JDBC container resources [{0}]", this );
|
||||
cleanup();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enableReleases() {
|
||||
releasesEnabled = true;
|
||||
|
@ -590,4 +489,81 @@ public class JdbcCoordinatorImpl implements JdbcCoordinator {
|
|||
LOG.debugf( "Unable to release JDBC result set [%s]", e.getMessage() );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isActive() {
|
||||
return !closed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterTransactionBegin() {
|
||||
owner.afterTransactionBegin();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeTransactionCompletion() {
|
||||
owner.beforeTransactionCompletion();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterTransactionCompletion(boolean successful) {
|
||||
afterTransaction();
|
||||
owner.afterTransactionCompletion( successful );
|
||||
}
|
||||
|
||||
@Override
|
||||
public JdbcSessionOwner getJdbcSessionOwner() {
|
||||
return this.owner;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataStoreTransaction getResourceLocalTransaction() {
|
||||
return logicalConnection.getPhysicalJdbcTransaction();
|
||||
}
|
||||
|
||||
/**
|
||||
* JDK serialization hook
|
||||
*
|
||||
* @param oos The stream into which to write our state
|
||||
*
|
||||
* @throws IOException Trouble accessing the stream
|
||||
*/
|
||||
public void serialize(ObjectOutputStream oos) throws IOException {
|
||||
if ( ! isReadyForSerialization() ) {
|
||||
throw new HibernateException( "Cannot serialize Session while connected" );
|
||||
}
|
||||
oos.writeBoolean( isUserSuppliedConnection );
|
||||
oos.writeObject( connectionReleaseMode );
|
||||
logicalConnection.serialize( oos );
|
||||
}
|
||||
|
||||
/**
|
||||
* JDK deserialization hook
|
||||
*
|
||||
* @param ois The stream into which to write our state
|
||||
* @param JdbcSessionOwner The Jdbc Session owner which owns the JdbcCoordinatorImpl to be deserialized.
|
||||
*
|
||||
* @return The deserialized JdbcCoordinatorImpl
|
||||
*
|
||||
* @throws IOException Trouble accessing the stream
|
||||
* @throws ClassNotFoundException Trouble reading the stream
|
||||
*/
|
||||
public static JdbcCoordinatorImpl deserialize(
|
||||
ObjectInputStream ois,
|
||||
JdbcSessionOwner owner) throws IOException, ClassNotFoundException {
|
||||
final boolean isUserSuppliedConnection = ois.readBoolean();
|
||||
final ConnectionReleaseMode connectionReleaseMode = (ConnectionReleaseMode) ois.readObject();
|
||||
LogicalConnectionImplementor logicalConnection;
|
||||
if ( isUserSuppliedConnection ) {
|
||||
logicalConnection = LogicalConnectionProvidedImpl.deserialize( ois );
|
||||
}
|
||||
else {
|
||||
logicalConnection = LogicalConnectionManagedImpl.deserialize(
|
||||
ois,
|
||||
owner.getJdbcConnectionAccess(),
|
||||
owner.getJdbcSessionContext()
|
||||
);
|
||||
}
|
||||
return new JdbcCoordinatorImpl( logicalConnection, isUserSuppliedConnection, connectionReleaseMode, owner );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,393 +0,0 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2010, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.engine.jdbc.internal;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.ConnectionReleaseMode;
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.JDBCException;
|
||||
import org.hibernate.engine.jdbc.connections.spi.JdbcConnectionAccess;
|
||||
import org.hibernate.engine.jdbc.spi.ConnectionObserver;
|
||||
import org.hibernate.engine.jdbc.spi.JdbcServices;
|
||||
import org.hibernate.engine.jdbc.spi.LogicalConnectionImplementor;
|
||||
import org.hibernate.engine.jdbc.spi.NonDurableConnectionObserver;
|
||||
import org.hibernate.engine.transaction.spi.TransactionContext;
|
||||
import org.hibernate.internal.CoreMessageLogger;
|
||||
import org.hibernate.internal.util.collections.CollectionHelper;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
/**
|
||||
* Standard Hibernate {@link org.hibernate.engine.jdbc.spi.LogicalConnection} implementation
|
||||
* <p/>
|
||||
* IMPL NOTE : Custom serialization handling!
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
* @author Brett Meyer
|
||||
*/
|
||||
public class LogicalConnectionImpl implements LogicalConnectionImplementor {
|
||||
private static final CoreMessageLogger LOG = Logger.getMessageLogger(
|
||||
CoreMessageLogger.class,
|
||||
LogicalConnectionImpl.class.getName()
|
||||
);
|
||||
|
||||
private transient Connection physicalConnection;
|
||||
|
||||
private final transient ConnectionReleaseMode connectionReleaseMode;
|
||||
private final transient JdbcServices jdbcServices;
|
||||
private final transient JdbcConnectionAccess jdbcConnectionAccess;
|
||||
private final transient List<ConnectionObserver> observers;
|
||||
|
||||
private final boolean isUserSuppliedConnection;
|
||||
|
||||
private boolean isClosed;
|
||||
|
||||
/**
|
||||
* Constructs a LogicalConnectionImpl
|
||||
*
|
||||
* @param userSuppliedConnection The user-supplied connection
|
||||
* @param connectionReleaseMode The connection release mode to use
|
||||
* @param jdbcServices JdbcServices
|
||||
* @param jdbcConnectionAccess JDBC Connection access
|
||||
*/
|
||||
public LogicalConnectionImpl(
|
||||
Connection userSuppliedConnection,
|
||||
ConnectionReleaseMode connectionReleaseMode,
|
||||
JdbcServices jdbcServices,
|
||||
JdbcConnectionAccess jdbcConnectionAccess) {
|
||||
this(
|
||||
connectionReleaseMode,
|
||||
jdbcServices,
|
||||
jdbcConnectionAccess,
|
||||
(userSuppliedConnection != null),
|
||||
false,
|
||||
new ArrayList<ConnectionObserver>()
|
||||
);
|
||||
this.physicalConnection = userSuppliedConnection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a LogicalConnectionImpl. This for used from deserialization
|
||||
*/
|
||||
private LogicalConnectionImpl(
|
||||
ConnectionReleaseMode connectionReleaseMode,
|
||||
JdbcServices jdbcServices,
|
||||
JdbcConnectionAccess jdbcConnectionAccess,
|
||||
boolean isUserSuppliedConnection,
|
||||
boolean isClosed,
|
||||
List<ConnectionObserver> observers) {
|
||||
this.connectionReleaseMode = determineConnectionReleaseMode(
|
||||
jdbcConnectionAccess, isUserSuppliedConnection, connectionReleaseMode
|
||||
);
|
||||
this.jdbcServices = jdbcServices;
|
||||
this.jdbcConnectionAccess = jdbcConnectionAccess;
|
||||
this.observers = observers;
|
||||
|
||||
this.isUserSuppliedConnection = isUserSuppliedConnection;
|
||||
this.isClosed = isClosed;
|
||||
}
|
||||
|
||||
private static 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 JdbcServices getJdbcServices() {
|
||||
return jdbcServices;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addObserver(ConnectionObserver observer) {
|
||||
observers.add( observer );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeObserver(ConnectionObserver connectionObserver) {
|
||||
observers.remove( connectionObserver );
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOpen() {
|
||||
return !isClosed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPhysicallyConnected() {
|
||||
return physicalConnection != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Connection getConnection() throws HibernateException {
|
||||
if ( isClosed ) {
|
||||
throw new HibernateException( "Logical connection is closed" );
|
||||
}
|
||||
if ( physicalConnection == null ) {
|
||||
if ( isUserSuppliedConnection ) {
|
||||
// should never happen
|
||||
throw new HibernateException( "User-supplied connection was null" );
|
||||
}
|
||||
obtainConnection();
|
||||
}
|
||||
return physicalConnection;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Connection close() {
|
||||
LOG.trace( "Closing logical connection" );
|
||||
final Connection c = isUserSuppliedConnection ? physicalConnection : null;
|
||||
try {
|
||||
if ( !isUserSuppliedConnection && physicalConnection != null ) {
|
||||
releaseConnection();
|
||||
}
|
||||
return c;
|
||||
}
|
||||
finally {
|
||||
// no matter what
|
||||
physicalConnection = null;
|
||||
isClosed = true;
|
||||
LOG.trace( "Logical connection closed" );
|
||||
for ( ConnectionObserver observer : observers ) {
|
||||
observer.logicalConnectionClosed();
|
||||
}
|
||||
observers.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConnectionReleaseMode getConnectionReleaseMode() {
|
||||
return connectionReleaseMode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Force aggressive release of the underlying connection.
|
||||
*/
|
||||
@Override
|
||||
public void aggressiveRelease() {
|
||||
if ( isUserSuppliedConnection ) {
|
||||
LOG.debug( "Cannot aggressively release user-supplied connection; skipping" );
|
||||
}
|
||||
else {
|
||||
LOG.debug( "Aggressively releasing JDBC connection" );
|
||||
if ( physicalConnection != null ) {
|
||||
releaseConnection();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Physically opens a JDBC Connection.
|
||||
*
|
||||
* @throws org.hibernate.JDBCException Indicates problem opening a connection
|
||||
*/
|
||||
private void obtainConnection() throws JDBCException {
|
||||
LOG.debug( "Obtaining JDBC connection" );
|
||||
try {
|
||||
physicalConnection = jdbcConnectionAccess.obtainConnection();
|
||||
for ( ConnectionObserver observer : observers ) {
|
||||
observer.physicalConnectionObtained( physicalConnection );
|
||||
}
|
||||
LOG.debug( "Obtained JDBC connection" );
|
||||
}
|
||||
catch ( SQLException sqle) {
|
||||
throw getJdbcServices().getSqlExceptionHelper().convert( sqle, "Could not open connection" );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Physically closes the JDBC Connection.
|
||||
*
|
||||
* @throws JDBCException Indicates problem closing a connection
|
||||
*/
|
||||
@Override
|
||||
public void releaseConnection() throws JDBCException {
|
||||
LOG.debug( "Releasing JDBC connection" );
|
||||
if ( physicalConnection == null ) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
if ( !physicalConnection.isClosed() ) {
|
||||
getJdbcServices().getSqlExceptionHelper().logAndClearWarnings( physicalConnection );
|
||||
}
|
||||
if ( !isUserSuppliedConnection ) {
|
||||
jdbcConnectionAccess.releaseConnection( physicalConnection );
|
||||
}
|
||||
}
|
||||
catch (SQLException e) {
|
||||
throw getJdbcServices().getSqlExceptionHelper().convert( e, "Could not close connection" );
|
||||
}
|
||||
finally {
|
||||
physicalConnection = null;
|
||||
}
|
||||
LOG.debug( "Released JDBC connection" );
|
||||
for ( ConnectionObserver observer : observers ) {
|
||||
observer.physicalConnectionReleased();
|
||||
}
|
||||
releaseNonDurableObservers();
|
||||
}
|
||||
|
||||
private void releaseNonDurableObservers() {
|
||||
final Iterator observers = this.observers.iterator();
|
||||
while ( observers.hasNext() ) {
|
||||
if ( NonDurableConnectionObserver.class.isInstance( observers.next() ) ) {
|
||||
observers.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Connection manualDisconnect() {
|
||||
if ( isClosed ) {
|
||||
throw new IllegalStateException( "cannot manually disconnect because logical connection is already closed" );
|
||||
}
|
||||
final Connection c = physicalConnection;
|
||||
releaseConnection();
|
||||
return c;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void manualReconnect(Connection suppliedConnection) {
|
||||
if ( isClosed ) {
|
||||
throw new IllegalStateException( "cannot manually reconnect because logical connection is already closed" );
|
||||
}
|
||||
if ( !isUserSuppliedConnection ) {
|
||||
throw new IllegalStateException( "cannot manually reconnect unless Connection was originally supplied" );
|
||||
}
|
||||
else {
|
||||
if ( suppliedConnection == null ) {
|
||||
throw new IllegalArgumentException( "cannot reconnect a null user-supplied connection" );
|
||||
}
|
||||
else if ( suppliedConnection == physicalConnection ) {
|
||||
LOG.debug( "reconnecting the same connection that is already connected; should this connection have been disconnected?" );
|
||||
}
|
||||
else if ( physicalConnection != null ) {
|
||||
throw new IllegalArgumentException(
|
||||
"cannot reconnect to a new user-supplied connection because currently connected; must disconnect before reconnecting."
|
||||
);
|
||||
}
|
||||
physicalConnection = suppliedConnection;
|
||||
LOG.debug( "Reconnected JDBC connection" );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAutoCommit() {
|
||||
if ( !isOpen() || ! isPhysicallyConnected() ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
try {
|
||||
return getConnection().getAutoCommit();
|
||||
}
|
||||
catch (SQLException e) {
|
||||
throw jdbcServices.getSqlExceptionHelper().convert( e, "could not inspect JDBC autocommit mode" );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isUserSuppliedConnection() {
|
||||
return isUserSuppliedConnection;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notifyObserversStatementPrepared() {
|
||||
for ( ConnectionObserver observer : observers ) {
|
||||
observer.statementPrepared();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Serialization hook
|
||||
*
|
||||
* @param oos The stream to write out state to
|
||||
*
|
||||
* @throws IOException Problem accessing stream
|
||||
*/
|
||||
public void serialize(ObjectOutputStream oos) throws IOException {
|
||||
oos.writeBoolean( isUserSuppliedConnection );
|
||||
oos.writeBoolean( isClosed );
|
||||
final List<ConnectionObserver> durableConnectionObservers = new ArrayList<ConnectionObserver>();
|
||||
for ( ConnectionObserver observer : observers ) {
|
||||
if ( ! NonDurableConnectionObserver.class.isInstance( observer ) ) {
|
||||
durableConnectionObservers.add( observer );
|
||||
}
|
||||
}
|
||||
oos.writeInt( durableConnectionObservers.size() );
|
||||
for ( ConnectionObserver observer : durableConnectionObservers ) {
|
||||
oos.writeObject( observer );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Deserialization hook
|
||||
*
|
||||
* @param ois The stream to read our state from
|
||||
* @param transactionContext The transactionContext which owns this logical connection
|
||||
*
|
||||
* @return The deserialized LogicalConnectionImpl
|
||||
*
|
||||
* @throws IOException Trouble accessing the stream
|
||||
* @throws ClassNotFoundException Trouble reading the stream
|
||||
*/
|
||||
public static LogicalConnectionImpl deserialize(
|
||||
ObjectInputStream ois,
|
||||
TransactionContext transactionContext) throws IOException, ClassNotFoundException {
|
||||
final boolean isUserSuppliedConnection = ois.readBoolean();
|
||||
final boolean isClosed = ois.readBoolean();
|
||||
final int observerCount = ois.readInt();
|
||||
final List<ConnectionObserver> observers = CollectionHelper.arrayList( observerCount );
|
||||
for ( int i = 0; i < observerCount; i++ ) {
|
||||
observers.add( (ConnectionObserver) ois.readObject() );
|
||||
}
|
||||
return new LogicalConnectionImpl(
|
||||
transactionContext.getConnectionReleaseMode(),
|
||||
transactionContext.getTransactionEnvironment().getJdbcServices(),
|
||||
transactionContext.getJdbcConnectionAccess(),
|
||||
isUserSuppliedConnection,
|
||||
isClosed,
|
||||
observers
|
||||
);
|
||||
}
|
||||
}
|
|
@ -55,11 +55,13 @@ public class ResultSetReturnImpl implements ResultSetReturn {
|
|||
public ResultSetReturnImpl(JdbcCoordinator jdbcCoordinator) {
|
||||
this.jdbcCoordinator = jdbcCoordinator;
|
||||
|
||||
final JdbcServices jdbcServices = jdbcCoordinator.getTransactionCoordinator().getTransactionContext()
|
||||
.getTransactionEnvironment()
|
||||
.getJdbcServices();
|
||||
final JdbcServices jdbcServices = jdbcCoordinator.getJdbcSessionOwner()
|
||||
.getJdbcSessionContext()
|
||||
.getServiceRegistry()
|
||||
.getService( JdbcServices.class );
|
||||
|
||||
this.dialect = jdbcServices.getDialect();
|
||||
|
||||
this.sqlStatementLogger = jdbcServices.getSqlStatementLogger();
|
||||
this.sqlExceptionHelper = jdbcServices.getSqlExceptionHelper();
|
||||
}
|
||||
|
@ -78,11 +80,11 @@ public class ResultSetReturnImpl implements ResultSetReturn {
|
|||
try {
|
||||
final ResultSet rs;
|
||||
try {
|
||||
jdbcCoordinator.getTransactionCoordinator().getTransactionContext().startStatementExecution();
|
||||
jdbcExecuteStatementStart();
|
||||
rs = statement.executeQuery();
|
||||
}
|
||||
finally {
|
||||
jdbcCoordinator.getTransactionCoordinator().getTransactionContext().endStatementExecution();
|
||||
jdbcExecuteStatementEnd();
|
||||
}
|
||||
postExtract( rs, statement );
|
||||
return rs;
|
||||
|
@ -92,6 +94,14 @@ public class ResultSetReturnImpl implements ResultSetReturn {
|
|||
}
|
||||
}
|
||||
|
||||
private void jdbcExecuteStatementEnd() {
|
||||
jdbcCoordinator.getJdbcSessionOwner().getJdbcSessionContext().getObserver().jdbcExecuteStatementEnd();
|
||||
}
|
||||
|
||||
private void jdbcExecuteStatementStart() {
|
||||
jdbcCoordinator.getJdbcSessionOwner().getJdbcSessionContext().getObserver().jdbcExecuteStatementStart();
|
||||
}
|
||||
|
||||
private boolean isTypeOf(final Statement statement, final Class<? extends Statement> type) {
|
||||
if (isJdbc4) {
|
||||
try {
|
||||
|
@ -117,11 +127,11 @@ public class ResultSetReturnImpl implements ResultSetReturn {
|
|||
try {
|
||||
final ResultSet rs;
|
||||
try {
|
||||
jdbcCoordinator.getTransactionCoordinator().getTransactionContext().startStatementExecution();
|
||||
jdbcExecuteStatementStart();
|
||||
rs = dialect.getResultSet( callableStatement );
|
||||
}
|
||||
finally {
|
||||
jdbcCoordinator.getTransactionCoordinator().getTransactionContext().endStatementExecution();
|
||||
jdbcExecuteStatementEnd();
|
||||
}
|
||||
postExtract( rs, callableStatement );
|
||||
return rs;
|
||||
|
@ -137,11 +147,11 @@ public class ResultSetReturnImpl implements ResultSetReturn {
|
|||
try {
|
||||
final ResultSet rs;
|
||||
try {
|
||||
jdbcCoordinator.getTransactionCoordinator().getTransactionContext().startStatementExecution();
|
||||
jdbcExecuteStatementStart();
|
||||
rs = statement.executeQuery( sql );
|
||||
}
|
||||
finally {
|
||||
jdbcCoordinator.getTransactionCoordinator().getTransactionContext().endStatementExecution();
|
||||
jdbcExecuteStatementEnd();
|
||||
}
|
||||
postExtract( rs, statement );
|
||||
return rs;
|
||||
|
@ -157,7 +167,7 @@ public class ResultSetReturnImpl implements ResultSetReturn {
|
|||
try {
|
||||
final ResultSet rs;
|
||||
try {
|
||||
jdbcCoordinator.getTransactionCoordinator().getTransactionContext().startStatementExecution();
|
||||
jdbcExecuteStatementStart();
|
||||
if ( !statement.execute() ) {
|
||||
while ( !statement.getMoreResults() && statement.getUpdateCount() != -1 ) {
|
||||
// do nothing until we hit the resultset
|
||||
|
@ -166,7 +176,7 @@ public class ResultSetReturnImpl implements ResultSetReturn {
|
|||
rs = statement.getResultSet();
|
||||
}
|
||||
finally {
|
||||
jdbcCoordinator.getTransactionCoordinator().getTransactionContext().endStatementExecution();
|
||||
jdbcExecuteStatementEnd();
|
||||
}
|
||||
postExtract( rs, statement );
|
||||
return rs;
|
||||
|
@ -182,7 +192,7 @@ public class ResultSetReturnImpl implements ResultSetReturn {
|
|||
try {
|
||||
final ResultSet rs;
|
||||
try {
|
||||
jdbcCoordinator.getTransactionCoordinator().getTransactionContext().startStatementExecution();
|
||||
jdbcExecuteStatementStart();
|
||||
if ( !statement.execute( sql ) ) {
|
||||
while ( !statement.getMoreResults() && statement.getUpdateCount() != -1 ) {
|
||||
// do nothing until we hit the resultset
|
||||
|
@ -191,7 +201,7 @@ public class ResultSetReturnImpl implements ResultSetReturn {
|
|||
rs = statement.getResultSet();
|
||||
}
|
||||
finally {
|
||||
jdbcCoordinator.getTransactionCoordinator().getTransactionContext().endStatementExecution();
|
||||
jdbcExecuteStatementEnd();
|
||||
}
|
||||
postExtract( rs, statement );
|
||||
return rs;
|
||||
|
@ -204,14 +214,14 @@ public class ResultSetReturnImpl implements ResultSetReturn {
|
|||
@Override
|
||||
public int executeUpdate(PreparedStatement statement) {
|
||||
try {
|
||||
jdbcCoordinator.getTransactionCoordinator().getTransactionContext().startStatementExecution();
|
||||
jdbcExecuteStatementStart();
|
||||
return statement.executeUpdate();
|
||||
}
|
||||
catch (SQLException e) {
|
||||
throw sqlExceptionHelper.convert( e, "could not execute statement" );
|
||||
}
|
||||
finally {
|
||||
jdbcCoordinator.getTransactionCoordinator().getTransactionContext().endStatementExecution();
|
||||
jdbcExecuteStatementEnd();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -219,20 +229,20 @@ public class ResultSetReturnImpl implements ResultSetReturn {
|
|||
public int executeUpdate(Statement statement, String sql) {
|
||||
sqlStatementLogger.logStatement( sql );
|
||||
try {
|
||||
jdbcCoordinator.getTransactionCoordinator().getTransactionContext().startStatementExecution();
|
||||
jdbcExecuteStatementStart();
|
||||
return statement.executeUpdate( sql );
|
||||
}
|
||||
catch (SQLException e) {
|
||||
throw sqlExceptionHelper.convert( e, "could not execute statement" );
|
||||
}
|
||||
finally {
|
||||
jdbcCoordinator.getTransactionCoordinator().getTransactionContext().endStatementExecution();
|
||||
jdbcExecuteStatementEnd();
|
||||
}
|
||||
}
|
||||
|
||||
private void postExtract(ResultSet rs, Statement st) {
|
||||
if ( rs != null ) {
|
||||
jdbcCoordinator.register( rs, st );
|
||||
jdbcCoordinator.getResourceRegistry().register( rs, st );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -32,9 +32,10 @@ import java.sql.Statement;
|
|||
import org.hibernate.AssertionFailure;
|
||||
import org.hibernate.ScrollMode;
|
||||
import org.hibernate.cfg.Settings;
|
||||
import org.hibernate.engine.jdbc.spi.LogicalConnectionImplementor;
|
||||
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.LogicalConnectionImplementor;
|
||||
|
||||
/**
|
||||
* Standard implementation of StatementPreparer
|
||||
|
@ -60,7 +61,7 @@ class StatementPreparerImpl implements StatementPreparer {
|
|||
}
|
||||
|
||||
protected final Connection connection() {
|
||||
return logicalConnection().getConnection();
|
||||
return logicalConnection().getPhysicalConnection();
|
||||
}
|
||||
|
||||
protected final LogicalConnectionImplementor logicalConnection() {
|
||||
|
@ -68,16 +69,14 @@ class StatementPreparerImpl implements StatementPreparer {
|
|||
}
|
||||
|
||||
protected final SqlExceptionHelper sqlExceptionHelper() {
|
||||
return jdbcCoordinator.getTransactionCoordinator().getTransactionContext().getTransactionEnvironment()
|
||||
.getJdbcServices()
|
||||
.getSqlExceptionHelper();
|
||||
return getJdbcService().getSqlExceptionHelper();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Statement createStatement() {
|
||||
try {
|
||||
final Statement statement = connection().createStatement();
|
||||
jdbcCoordinator.register( statement );
|
||||
jdbcCoordinator.getResourceRegistry().register( statement, true );
|
||||
return statement;
|
||||
}
|
||||
catch ( SQLException e ) {
|
||||
|
@ -173,21 +172,23 @@ class StatementPreparerImpl implements StatementPreparer {
|
|||
protected final String sql;
|
||||
|
||||
protected StatementPreparationTemplate(String sql) {
|
||||
this.sql = jdbcCoordinator.getTransactionCoordinator().getTransactionContext().onPrepareStatement( sql );
|
||||
this.sql = jdbcCoordinator.getJdbcSessionOwner().getJdbcSessionContext().getStatementInspector().inspect(
|
||||
sql
|
||||
);
|
||||
}
|
||||
|
||||
public PreparedStatement prepareStatement() {
|
||||
try {
|
||||
jdbcCoordinator.getLogicalConnection().getJdbcServices().getSqlStatementLogger().logStatement( sql );
|
||||
getJdbcService().getSqlStatementLogger().logStatement( sql );
|
||||
|
||||
final PreparedStatement preparedStatement;
|
||||
try {
|
||||
jdbcCoordinator.getTransactionCoordinator().getTransactionContext().startPrepareStatement();
|
||||
jdbcCoordinator.getJdbcSessionOwner().getJdbcSessionContext().getObserver().jdbcPrepareStatementStart();
|
||||
preparedStatement = doPrepare();
|
||||
setStatementTimeout( preparedStatement );
|
||||
}
|
||||
finally {
|
||||
jdbcCoordinator.getTransactionCoordinator().getTransactionContext().endPrepareStatement();
|
||||
jdbcCoordinator.getJdbcSessionOwner().getJdbcSessionContext().getObserver().jdbcPrepareStatementEnd();
|
||||
}
|
||||
postProcess( preparedStatement );
|
||||
return preparedStatement;
|
||||
|
@ -200,8 +201,8 @@ class StatementPreparerImpl implements StatementPreparer {
|
|||
protected abstract PreparedStatement doPrepare() throws SQLException;
|
||||
|
||||
public void postProcess(PreparedStatement preparedStatement) throws SQLException {
|
||||
jdbcCoordinator.register( preparedStatement );
|
||||
logicalConnection().notifyObserversStatementPrepared();
|
||||
jdbcCoordinator.getResourceRegistry().register( preparedStatement, true );
|
||||
// logicalConnection().notifyObserversStatementPrepared();
|
||||
}
|
||||
|
||||
private void setStatementTimeout(PreparedStatement preparedStatement) throws SQLException {
|
||||
|
@ -212,6 +213,14 @@ class StatementPreparerImpl implements StatementPreparer {
|
|||
}
|
||||
}
|
||||
|
||||
private JdbcServices getJdbcService() {
|
||||
return jdbcCoordinator
|
||||
.getJdbcSessionOwner()
|
||||
.getJdbcSessionContext()
|
||||
.getServiceRegistry()
|
||||
.getService( JdbcServices.class );
|
||||
}
|
||||
|
||||
private abstract class QueryStatementPreparationTemplate extends StatementPreparationTemplate {
|
||||
protected QueryStatementPreparationTemplate(String sql) {
|
||||
super( sql );
|
||||
|
|
|
@ -25,13 +25,17 @@ package org.hibernate.engine.jdbc.spi;
|
|||
|
||||
import java.io.Serializable;
|
||||
import java.sql.Connection;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.Statement;
|
||||
|
||||
import org.hibernate.ConnectionReleaseMode;
|
||||
import org.hibernate.engine.jdbc.batch.spi.Batch;
|
||||
import org.hibernate.engine.jdbc.batch.spi.BatchKey;
|
||||
import org.hibernate.engine.transaction.spi.TransactionCoordinator;
|
||||
import org.hibernate.jdbc.WorkExecutorVisitable;
|
||||
import org.hibernate.resource.jdbc.ResourceRegistry;
|
||||
import org.hibernate.resource.jdbc.spi.LogicalConnectionImplementor;
|
||||
import org.hibernate.resource.transaction.TransactionCoordinator;
|
||||
import org.hibernate.resource.transaction.backend.store.spi.DataStoreTransactionAccess;
|
||||
import org.hibernate.resource.transaction.spi.TransactionCoordinatorOwner;
|
||||
|
||||
/**
|
||||
* Coordinates JDBC-related activities.
|
||||
|
@ -39,13 +43,13 @@ import org.hibernate.jdbc.WorkExecutorVisitable;
|
|||
* @author Steve Ebersole
|
||||
* @author Brett Meyer
|
||||
*/
|
||||
public interface JdbcCoordinator extends Serializable {
|
||||
/**
|
||||
* Retrieve the transaction coordinator associated with this JDBC coordinator.
|
||||
*
|
||||
* @return The transaction coordinator
|
||||
*/
|
||||
public TransactionCoordinator getTransactionCoordinator();
|
||||
public interface JdbcCoordinator extends Serializable, TransactionCoordinatorOwner, DataStoreTransactionAccess {
|
||||
// /**
|
||||
// * Retrieve the transaction coordinator associated with this JDBC coordinator.
|
||||
// *
|
||||
// * @return The transaction coordinator
|
||||
// */
|
||||
// public TransactionCoordinator getTransactionCoordinator();
|
||||
|
||||
/**
|
||||
* Retrieves the logical connection associated with this JDBC coordinator.
|
||||
|
@ -105,7 +109,7 @@ public interface JdbcCoordinator extends Serializable {
|
|||
*
|
||||
* @return The {@link Connection} associated with the managed {@link #getLogicalConnection() logical connection}
|
||||
*
|
||||
* @see LogicalConnection#close
|
||||
* @see org.hibernate.resource.jdbc.spi.LogicalConnectionImplementor#close
|
||||
*/
|
||||
public Connection close();
|
||||
|
||||
|
@ -138,13 +142,6 @@ public interface JdbcCoordinator extends Serializable {
|
|||
*/
|
||||
public void cancelLastQuery();
|
||||
|
||||
/**
|
||||
* Set the effective transaction timeout period for the current transaction, in seconds.
|
||||
*
|
||||
* @param seconds The number of seconds before a time out should occur.
|
||||
*/
|
||||
public void setTransactionTimeOut(int seconds);
|
||||
|
||||
/**
|
||||
* Calculate the amount of time, in seconds, still remaining before transaction timeout occurs.
|
||||
*
|
||||
|
@ -155,52 +152,6 @@ public interface JdbcCoordinator extends Serializable {
|
|||
*/
|
||||
public int determineRemainingTransactionTimeOutPeriod();
|
||||
|
||||
/**
|
||||
* Register a JDBC statement.
|
||||
*
|
||||
* @param statement The statement to register.
|
||||
*/
|
||||
public void register(Statement statement);
|
||||
|
||||
/**
|
||||
* Release a previously registered statement.
|
||||
*
|
||||
* @param statement The statement to release.
|
||||
*/
|
||||
public void release(Statement statement);
|
||||
|
||||
/**
|
||||
* Register a JDBC result set.
|
||||
* <p/>
|
||||
* Implementation note: Second parameter has been introduced to prevent
|
||||
* multiple registrations of the same statement in case {@link ResultSet#getStatement()}
|
||||
* does not return original {@link Statement} object.
|
||||
*
|
||||
* @param resultSet The result set to register.
|
||||
* @param statement Statement from which {@link ResultSet} has been generated.
|
||||
*/
|
||||
public void register(ResultSet resultSet, Statement statement);
|
||||
|
||||
/**
|
||||
* Release a previously registered result set.
|
||||
*
|
||||
* @param resultSet The result set to release.
|
||||
* @param statement Statement from which {@link ResultSet} has been generated.
|
||||
*/
|
||||
public void release(ResultSet resultSet, Statement statement);
|
||||
|
||||
/**
|
||||
* Does this registry currently have any registered resources?
|
||||
*
|
||||
* @return True if the registry does have registered resources; false otherwise.
|
||||
*/
|
||||
public boolean hasRegisteredResources();
|
||||
|
||||
/**
|
||||
* Release all registered resources.
|
||||
*/
|
||||
public void releaseResources();
|
||||
|
||||
/**
|
||||
* Enable connection releases
|
||||
*/
|
||||
|
@ -224,4 +175,13 @@ public interface JdbcCoordinator extends Serializable {
|
|||
* @return {@code true} indicates the coordinator can be serialized.
|
||||
*/
|
||||
public boolean isReadyForSerialization();
|
||||
|
||||
/**
|
||||
* The release mode under which this logical connection is operating.
|
||||
*
|
||||
* @return the release mode.
|
||||
*/
|
||||
public ConnectionReleaseMode getConnectionReleaseMode();
|
||||
|
||||
public ResourceRegistry getResourceRegistry();
|
||||
}
|
||||
|
|
|
@ -1,71 +0,0 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2010, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.engine.jdbc.spi;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.sql.Connection;
|
||||
|
||||
/**
|
||||
* LogicalConnection contract
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface LogicalConnection extends Serializable {
|
||||
/**
|
||||
* Is this logical connection open? Another phraseology sometimes used is: "are we
|
||||
* logically connected"?
|
||||
*
|
||||
* @return True if logically connected; false otherwise.
|
||||
*/
|
||||
public boolean isOpen();
|
||||
|
||||
/**
|
||||
* Is this logical connection instance "physically" connected. Meaning
|
||||
* do we currently internally have a cached connection.
|
||||
*
|
||||
* @return True if physically connected; false otherwise.
|
||||
*/
|
||||
public boolean isPhysicallyConnected();
|
||||
|
||||
/**
|
||||
* Retrieves the connection currently "logically" managed by this LogicalConnectionImpl.
|
||||
* <p/>
|
||||
* Note, that we may need to obtain a connection to return here if a
|
||||
* connection has either not yet been obtained (non-UserSuppliedConnectionProvider)
|
||||
* or has previously been aggressively released.
|
||||
*
|
||||
* @return The current Connection.
|
||||
*/
|
||||
public Connection getConnection();
|
||||
|
||||
/**
|
||||
* Release the underlying connection and clean up any other resources associated
|
||||
* with this logical connection.
|
||||
* <p/>
|
||||
* This leaves the logical connection in a "no longer usable" state.
|
||||
*
|
||||
* @return The application-supplied connection, or {@code null} if Hibernate was managing connection.
|
||||
*/
|
||||
public Connection close();
|
||||
}
|
|
@ -202,17 +202,18 @@ public class NativeSQLQueryPlan implements Serializable {
|
|||
queryParameters.processFilters( this.customQuery.getSQL(), session );
|
||||
final String sql = queryParameters.getFilteredSQL();
|
||||
|
||||
ps = session.getTransactionCoordinator().getJdbcCoordinator().getStatementPreparer().prepareStatement( sql, false );
|
||||
ps = session.getJdbcCoordinator().getStatementPreparer().prepareStatement( sql, false );
|
||||
|
||||
try {
|
||||
int col = 1;
|
||||
col += bindPositionalParameters( ps, queryParameters, col, session );
|
||||
col += bindNamedParameters( ps, queryParameters.getNamedParameters(), col, session );
|
||||
result = session.getTransactionCoordinator().getJdbcCoordinator().getResultSetReturn().executeUpdate( ps );
|
||||
result = session.getJdbcCoordinator().getResultSetReturn().executeUpdate( ps );
|
||||
}
|
||||
finally {
|
||||
if ( ps != null ) {
|
||||
session.getTransactionCoordinator().getJdbcCoordinator().release( ps );
|
||||
session.getJdbcCoordinator().getResourceRegistry().release( ps );
|
||||
session.getJdbcCoordinator().afterStatementExecution();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -481,7 +481,7 @@ public class ActionQueue {
|
|||
}
|
||||
|
||||
list.clear();
|
||||
session.getTransactionCoordinator().getJdbcCoordinator().executeBatch();
|
||||
session.getJdbcCoordinator().executeBatch();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -56,13 +56,14 @@ import org.hibernate.UnknownProfileException;
|
|||
import org.hibernate.cache.spi.CacheKey;
|
||||
import org.hibernate.collection.spi.PersistentCollection;
|
||||
import org.hibernate.engine.jdbc.connections.spi.JdbcConnectionAccess;
|
||||
import org.hibernate.engine.jdbc.spi.JdbcCoordinator;
|
||||
import org.hibernate.engine.query.spi.sql.NativeSQLQuerySpecification;
|
||||
import org.hibernate.engine.transaction.spi.TransactionCoordinator;
|
||||
import org.hibernate.jdbc.ReturningWork;
|
||||
import org.hibernate.jdbc.Work;
|
||||
import org.hibernate.loader.custom.CustomQuery;
|
||||
import org.hibernate.persister.entity.EntityPersister;
|
||||
import org.hibernate.procedure.ProcedureCall;
|
||||
import org.hibernate.resource.transaction.TransactionCoordinator;
|
||||
import org.hibernate.stat.SessionStatistics;
|
||||
import org.hibernate.type.Type;
|
||||
|
||||
|
@ -359,11 +360,26 @@ public class SessionDelegatorBaseImpl implements SessionImplementor, Session {
|
|||
return sessionImplementor.getTransactionCoordinator();
|
||||
}
|
||||
|
||||
@Override
|
||||
public JdbcCoordinator getJdbcCoordinator() {
|
||||
return sessionImplementor.getJdbcCoordinator();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isClosed() {
|
||||
return sessionImplementor.isClosed();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldAutoClose() {
|
||||
return sessionImplementor.shouldAutoClose();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAutoCloseSessionEnabled() {
|
||||
return sessionImplementor.isAutoCloseSessionEnabled();
|
||||
}
|
||||
|
||||
@Override
|
||||
public LoadQueryInfluencers getLoadQueryInfluencers() {
|
||||
return sessionImplementor.getLoadQueryInfluencers();
|
||||
|
|
|
@ -38,14 +38,16 @@ import org.hibernate.Query;
|
|||
import org.hibernate.SQLQuery;
|
||||
import org.hibernate.ScrollMode;
|
||||
import org.hibernate.ScrollableResults;
|
||||
import org.hibernate.Transaction;
|
||||
import org.hibernate.cache.spi.CacheKey;
|
||||
import org.hibernate.collection.spi.PersistentCollection;
|
||||
import org.hibernate.engine.jdbc.LobCreationContext;
|
||||
import org.hibernate.engine.jdbc.connections.spi.JdbcConnectionAccess;
|
||||
import org.hibernate.engine.jdbc.spi.JdbcCoordinator;
|
||||
import org.hibernate.engine.query.spi.sql.NativeSQLQuerySpecification;
|
||||
import org.hibernate.engine.transaction.spi.TransactionCoordinator;
|
||||
import org.hibernate.loader.custom.CustomQuery;
|
||||
import org.hibernate.persister.entity.EntityPersister;
|
||||
import org.hibernate.resource.transaction.TransactionCoordinator;
|
||||
import org.hibernate.type.Type;
|
||||
|
||||
/**
|
||||
|
@ -384,6 +386,8 @@ public interface SessionImplementor extends Serializable, LobCreationContext {
|
|||
*/
|
||||
public TransactionCoordinator getTransactionCoordinator();
|
||||
|
||||
public JdbcCoordinator getJdbcCoordinator();
|
||||
|
||||
/**
|
||||
* Determine whether the session is closed. Provided separately from
|
||||
* {@link #isOpen()} as this method does not attempt any JTA synchronization
|
||||
|
@ -394,6 +398,10 @@ public interface SessionImplementor extends Serializable, LobCreationContext {
|
|||
*/
|
||||
public boolean isClosed();
|
||||
|
||||
public boolean shouldAutoClose();
|
||||
|
||||
public boolean isAutoCloseSessionEnabled();
|
||||
|
||||
/**
|
||||
* Get the load query influencers associated with this session.
|
||||
*
|
||||
|
|
|
@ -1,398 +0,0 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2011, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.engine.transaction.internal;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.sql.Connection;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.ConnectionReleaseMode;
|
||||
import org.hibernate.ResourceClosedException;
|
||||
import org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl;
|
||||
import org.hibernate.engine.jdbc.spi.JdbcCoordinator;
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.engine.transaction.internal.jta.JtaStatusHelper;
|
||||
import org.hibernate.engine.transaction.jta.platform.spi.JtaPlatform;
|
||||
import org.hibernate.engine.transaction.spi.JoinStatus;
|
||||
import org.hibernate.engine.transaction.spi.SynchronizationRegistry;
|
||||
import org.hibernate.engine.transaction.spi.TransactionContext;
|
||||
import org.hibernate.engine.transaction.spi.TransactionCoordinator;
|
||||
import org.hibernate.engine.transaction.spi.TransactionEnvironment;
|
||||
import org.hibernate.engine.transaction.spi.TransactionFactory;
|
||||
import org.hibernate.engine.transaction.spi.TransactionImplementor;
|
||||
import org.hibernate.engine.transaction.spi.TransactionObserver;
|
||||
import org.hibernate.engine.transaction.synchronization.internal.RegisteredSynchronization;
|
||||
import org.hibernate.engine.transaction.synchronization.internal.SynchronizationCallbackCoordinatorNonTrackingImpl;
|
||||
import org.hibernate.engine.transaction.synchronization.internal.SynchronizationCallbackCoordinatorTrackingImpl;
|
||||
import org.hibernate.engine.transaction.synchronization.spi.SynchronizationCallbackCoordinator;
|
||||
import org.hibernate.internal.CoreLogging;
|
||||
import org.hibernate.internal.CoreMessageLogger;
|
||||
import org.hibernate.internal.util.collections.CollectionHelper;
|
||||
|
||||
/**
|
||||
* Standard implementation of the Hibernate {@link TransactionCoordinator}
|
||||
* <p/>
|
||||
* IMPL NOTE : Custom serialization handling!
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public final class TransactionCoordinatorImpl implements TransactionCoordinator {
|
||||
private static final CoreMessageLogger LOG = CoreLogging.messageLogger( TransactionCoordinatorImpl.class );
|
||||
|
||||
private final transient TransactionContext transactionContext;
|
||||
private final transient JdbcCoordinatorImpl jdbcCoordinator;
|
||||
private final transient TransactionFactory transactionFactory;
|
||||
private final transient TransactionEnvironment transactionEnvironment;
|
||||
|
||||
private final transient List<TransactionObserver> observers;
|
||||
private final transient SynchronizationRegistryImpl synchronizationRegistry;
|
||||
|
||||
private transient TransactionImplementor currentHibernateTransaction;
|
||||
|
||||
private transient SynchronizationCallbackCoordinator callbackCoordinator;
|
||||
|
||||
private transient boolean open = true;
|
||||
private transient boolean synchronizationRegistered;
|
||||
private transient boolean ownershipTaken;
|
||||
|
||||
private transient boolean isDebugging = LOG.isDebugEnabled();
|
||||
private transient boolean isTracing = LOG.isTraceEnabled();
|
||||
|
||||
public TransactionCoordinatorImpl(
|
||||
Connection userSuppliedConnection,
|
||||
TransactionContext transactionContext) {
|
||||
this.transactionContext = transactionContext;
|
||||
this.jdbcCoordinator = new JdbcCoordinatorImpl( userSuppliedConnection, this );
|
||||
this.transactionEnvironment = transactionContext.getTransactionEnvironment();
|
||||
this.transactionFactory = this.transactionEnvironment.getTransactionFactory();
|
||||
this.observers = new ArrayList<TransactionObserver>();
|
||||
this.synchronizationRegistry = new SynchronizationRegistryImpl();
|
||||
reset();
|
||||
|
||||
final boolean registerSynchronization = transactionContext.isAutoCloseSessionEnabled()
|
||||
|| transactionContext.isFlushBeforeCompletionEnabled()
|
||||
|| transactionContext.getConnectionReleaseMode() == ConnectionReleaseMode.AFTER_TRANSACTION;
|
||||
if ( registerSynchronization ) {
|
||||
pulse();
|
||||
}
|
||||
}
|
||||
|
||||
public TransactionCoordinatorImpl(
|
||||
TransactionContext transactionContext,
|
||||
JdbcCoordinatorImpl jdbcCoordinator,
|
||||
List<TransactionObserver> observers) {
|
||||
this.transactionContext = transactionContext;
|
||||
this.jdbcCoordinator = jdbcCoordinator;
|
||||
this.transactionEnvironment = transactionContext.getTransactionEnvironment();
|
||||
this.transactionFactory = this.transactionEnvironment.getTransactionFactory();
|
||||
this.observers = observers;
|
||||
this.synchronizationRegistry = new SynchronizationRegistryImpl();
|
||||
reset();
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the internal state.
|
||||
*/
|
||||
public void reset() {
|
||||
synchronizationRegistered = false;
|
||||
ownershipTaken = false;
|
||||
|
||||
if ( currentHibernateTransaction != null ) {
|
||||
currentHibernateTransaction.invalidate();
|
||||
}
|
||||
currentHibernateTransaction = transactionFactory().createTransaction( this );
|
||||
if ( transactionContext.shouldAutoJoinTransaction() ) {
|
||||
currentHibernateTransaction.markForJoin();
|
||||
currentHibernateTransaction.join();
|
||||
}
|
||||
|
||||
// IMPL NOTE : reset clears synchronizations (following jta spec), but not observers!
|
||||
synchronizationRegistry.clearSynchronizations();
|
||||
}
|
||||
|
||||
public void afterTransaction(TransactionImplementor hibernateTransaction, int status) {
|
||||
if (isTracing) {
|
||||
LOG.trace( "after transaction completion" );
|
||||
}
|
||||
|
||||
final boolean success = JtaStatusHelper.isCommitted( status );
|
||||
|
||||
if ( sessionFactory().getStatistics().isStatisticsEnabled() ) {
|
||||
transactionEnvironment.getStatisticsImplementor().endTransaction( success );
|
||||
}
|
||||
|
||||
getJdbcCoordinator().afterTransaction();
|
||||
|
||||
getTransactionContext().afterTransactionCompletion( hibernateTransaction, success );
|
||||
sendAfterTransactionCompletionNotifications( hibernateTransaction, status );
|
||||
reset();
|
||||
}
|
||||
|
||||
private SessionFactoryImplementor sessionFactory() {
|
||||
return transactionEnvironment.getSessionFactory();
|
||||
}
|
||||
|
||||
public boolean isSynchronizationRegistered() {
|
||||
return synchronizationRegistered;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings({"unchecked"})
|
||||
public boolean isTransactionInProgress() {
|
||||
return open && getTransaction().isActive() && getTransaction().getJoinStatus() == JoinStatus.JOINED;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TransactionContext getTransactionContext() {
|
||||
return transactionContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JdbcCoordinator getJdbcCoordinator() {
|
||||
return jdbcCoordinator;
|
||||
}
|
||||
|
||||
private TransactionFactory transactionFactory() {
|
||||
return transactionFactory;
|
||||
}
|
||||
|
||||
private TransactionEnvironment getTransactionEnvironment() {
|
||||
return transactionEnvironment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TransactionImplementor getTransaction() {
|
||||
if ( !open ) {
|
||||
throw new ResourceClosedException( "This TransactionCoordinator has been closed" );
|
||||
}
|
||||
pulse();
|
||||
return currentHibernateTransaction;
|
||||
}
|
||||
|
||||
public void afterNonTransactionalQuery(boolean success) {
|
||||
// check to see if the connection is in auto-commit mode (no connection means aggressive connection
|
||||
// release outside a JTA transaction context, so MUST be autocommit mode)
|
||||
boolean isAutocommit = getJdbcCoordinator().getLogicalConnection().isAutoCommit();
|
||||
getJdbcCoordinator().afterTransaction();
|
||||
|
||||
if ( isAutocommit ) {
|
||||
for ( TransactionObserver observer : observers ) {
|
||||
observer.afterCompletion( success, this.getTransaction() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resetJoinStatus() {
|
||||
getTransaction().resetJoinStatus();
|
||||
}
|
||||
|
||||
@SuppressWarnings({"unchecked"})
|
||||
private void attemptToRegisterJtaSync() {
|
||||
if ( synchronizationRegistered ) {
|
||||
return;
|
||||
}
|
||||
|
||||
final JtaPlatform jtaPlatform = getTransactionEnvironment().getJtaPlatform();
|
||||
if ( jtaPlatform == null ) {
|
||||
// if no jta platform was registered we wont be able to register a jta synchronization
|
||||
return;
|
||||
}
|
||||
|
||||
// Has the local transaction (Hibernate facade) taken on the responsibility of driving the transaction inflow?
|
||||
if ( currentHibernateTransaction.isInitiator() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
final JoinStatus joinStatus = currentHibernateTransaction.getJoinStatus();
|
||||
if ( joinStatus != JoinStatus.JOINED ) {
|
||||
// the transaction is not (yet) joined, see if we should join...
|
||||
if ( !transactionContext.shouldAutoJoinTransaction() ) {
|
||||
// we are supposed to not auto join transactions; if the transaction is not marked for join
|
||||
// we cannot go any further in attempting to join (register sync).
|
||||
if ( joinStatus != JoinStatus.MARKED_FOR_JOINED ) {
|
||||
if (isDebugging) {
|
||||
LOG.debug( "Skipping JTA sync registration due to auto join checking" );
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// IMPL NOTE : At this point the local callback is the "maybe" one. The only time that needs to change is if
|
||||
// we are able to successfully register the transaction synchronization in which case the local callback would become
|
||||
// non driving. To that end, the following checks are simply opt outs where we are unable to register the
|
||||
// synchronization
|
||||
|
||||
// Can we resister a synchronization
|
||||
if ( !jtaPlatform.canRegisterSynchronization() ) {
|
||||
if (isTracing) {
|
||||
LOG.trace( "registered JTA platform says we cannot currently register synchronization; skipping" );
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Should we resister a synchronization
|
||||
if ( !transactionFactory().isJoinableJtaTransaction( this, currentHibernateTransaction ) ) {
|
||||
if (isTracing) {
|
||||
LOG.trace( "TransactionFactory reported no JTA transaction to join; skipping Synchronization registration" );
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
jtaPlatform.registerSynchronization( new RegisteredSynchronization( getSynchronizationCallbackCoordinator() ) );
|
||||
getSynchronizationCallbackCoordinator().synchronizationRegistered();
|
||||
synchronizationRegistered = true;
|
||||
if (isDebugging) {
|
||||
LOG.debug( "successfully registered Synchronization" );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public SynchronizationCallbackCoordinator getSynchronizationCallbackCoordinator() {
|
||||
if ( callbackCoordinator == null ) {
|
||||
callbackCoordinator = transactionEnvironment.getSessionFactory().getSettings().isJtaTrackByThread()
|
||||
? new SynchronizationCallbackCoordinatorTrackingImpl( this )
|
||||
: new SynchronizationCallbackCoordinatorNonTrackingImpl( this );
|
||||
}
|
||||
return callbackCoordinator;
|
||||
}
|
||||
|
||||
public void pulse() {
|
||||
if ( transactionFactory().compatibleWithJtaSynchronization() ) {
|
||||
// the configured transaction strategy says it supports callbacks via JTA synchronization, so attempt to
|
||||
// register JTA synchronization if possible
|
||||
attemptToRegisterJtaSync();
|
||||
}
|
||||
}
|
||||
|
||||
public Connection close() {
|
||||
open = false;
|
||||
reset();
|
||||
observers.clear();
|
||||
return jdbcCoordinator.close();
|
||||
}
|
||||
|
||||
public SynchronizationRegistry getSynchronizationRegistry() {
|
||||
return synchronizationRegistry;
|
||||
}
|
||||
|
||||
public void addObserver(TransactionObserver observer) {
|
||||
observers.add( observer );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeObserver(TransactionObserver observer) {
|
||||
observers.remove( observer );
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings({"unchecked"})
|
||||
public boolean isTransactionJoinable() {
|
||||
return transactionFactory().isJoinableJtaTransaction( this, currentHibernateTransaction );
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings({"unchecked"})
|
||||
public boolean isTransactionJoined() {
|
||||
return currentHibernateTransaction != null && currentHibernateTransaction.getJoinStatus() == JoinStatus.JOINED;
|
||||
}
|
||||
|
||||
public void setRollbackOnly() {
|
||||
getTransaction().markRollbackOnly();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean takeOwnership() {
|
||||
if ( ownershipTaken ) {
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
ownershipTaken = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendAfterTransactionBeginNotifications(TransactionImplementor hibernateTransaction) {
|
||||
for ( TransactionObserver observer : observers ) {
|
||||
observer.afterBegin( currentHibernateTransaction );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendBeforeTransactionCompletionNotifications(TransactionImplementor hibernateTransaction) {
|
||||
synchronizationRegistry.notifySynchronizationsBeforeTransactionCompletion();
|
||||
for ( TransactionObserver observer : observers ) {
|
||||
observer.beforeCompletion( hibernateTransaction );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendAfterTransactionCompletionNotifications(TransactionImplementor hibernateTransaction, int status) {
|
||||
final boolean successful = JtaStatusHelper.isCommitted( status );
|
||||
for ( TransactionObserver observer : new ArrayList<TransactionObserver>( observers ) ) {
|
||||
observer.afterCompletion( successful, hibernateTransaction );
|
||||
}
|
||||
synchronizationRegistry.notifySynchronizationsAfterTransactionCompletion( status );
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isActive() {
|
||||
return !sessionFactory().isClosed();
|
||||
}
|
||||
|
||||
|
||||
// serialization ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
public void serialize(ObjectOutputStream oos) throws IOException {
|
||||
jdbcCoordinator.serialize( oos );
|
||||
oos.writeInt( observers.size() );
|
||||
for ( TransactionObserver observer : observers ) {
|
||||
oos.writeObject( observer );
|
||||
}
|
||||
}
|
||||
|
||||
public static TransactionCoordinatorImpl deserialize(
|
||||
ObjectInputStream ois,
|
||||
TransactionContext transactionContext) throws ClassNotFoundException, IOException {
|
||||
final JdbcCoordinatorImpl jdbcCoordinator = JdbcCoordinatorImpl.deserialize( ois, transactionContext );
|
||||
final int observerCount = ois.readInt();
|
||||
final List<TransactionObserver> observers = CollectionHelper.arrayList( observerCount );
|
||||
for ( int i = 0; i < observerCount; i++ ) {
|
||||
observers.add( (TransactionObserver) ois.readObject() );
|
||||
}
|
||||
final TransactionCoordinatorImpl transactionCoordinator = new TransactionCoordinatorImpl(
|
||||
transactionContext,
|
||||
jdbcCoordinator,
|
||||
observers
|
||||
);
|
||||
jdbcCoordinator.afterDeserialize( transactionCoordinator );
|
||||
return transactionCoordinator;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,144 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) {DATE}, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.engine.transaction.internal;
|
||||
|
||||
import javax.transaction.Synchronization;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.Transaction;
|
||||
import org.hibernate.TransactionException;
|
||||
import org.hibernate.internal.CoreLogging;
|
||||
import org.hibernate.resource.transaction.TransactionCoordinator;
|
||||
import org.hibernate.resource.transaction.spi.TransactionStatus;
|
||||
|
||||
import static org.hibernate.resource.transaction.TransactionCoordinator.LocalInflow;
|
||||
|
||||
/**
|
||||
* @author Andrea Boriero
|
||||
*/
|
||||
public class TransactionImpl implements Transaction {
|
||||
private static final Logger LOG = CoreLogging.logger( TransactionImpl.class );
|
||||
|
||||
private final TransactionCoordinator transactionCoordinator;
|
||||
private final LocalInflow transactionDriverControl;
|
||||
|
||||
private boolean valid = true;
|
||||
|
||||
public TransactionImpl(TransactionCoordinator transactionCoordinator) {
|
||||
this.transactionCoordinator = transactionCoordinator;
|
||||
this.transactionDriverControl = transactionCoordinator.getTransactionDriverControl();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void begin() {
|
||||
TransactionStatus status = transactionDriverControl.getStatus();
|
||||
|
||||
if ( !valid ) {
|
||||
throw new TransactionException( "Transaction instance is no longer valid" );
|
||||
}
|
||||
if ( status == TransactionStatus.ACTIVE ) {
|
||||
// throw new TransactionException( "nested transactions not supported" );
|
||||
return;
|
||||
}
|
||||
|
||||
LOG.debug( "begin" );
|
||||
this.transactionDriverControl.begin();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void commit() {
|
||||
TransactionStatus status = transactionDriverControl.getStatus();
|
||||
if ( status != TransactionStatus.ACTIVE ) {
|
||||
throw new TransactionException( "Transaction not successfully started" );
|
||||
}
|
||||
|
||||
LOG.debug( "committing" );
|
||||
|
||||
try {
|
||||
this.transactionDriverControl.commit();
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new TransactionException( "commit failed", e );
|
||||
}
|
||||
finally {
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rollback() {
|
||||
TransactionStatus status = transactionDriverControl.getStatus();
|
||||
if ( status != TransactionStatus.ACTIVE && status != TransactionStatus.FAILED_COMMIT ) {
|
||||
throw new TransactionException( "Transaction not successfully started" );
|
||||
}
|
||||
|
||||
LOG.debug( "rolling back" );
|
||||
if ( status != TransactionStatus.FAILED_COMMIT || allowFailedCommitToPhysicallyRollback() ) {
|
||||
try {
|
||||
this.transactionDriverControl.rollback();
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new TransactionException( "rollback failed", e );
|
||||
}
|
||||
finally {
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public TransactionStatus getStatus() {
|
||||
return transactionDriverControl.getStatus();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerSynchronization(Synchronization synchronization) throws HibernateException {
|
||||
this.transactionCoordinator.getLocalSynchronizations().registerSynchronization( synchronization );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTimeout(int seconds) {
|
||||
this.transactionCoordinator.setTimeOut( seconds );
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTimeout() {
|
||||
return this.transactionCoordinator.getTimeOut();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void markRollbackOnly() {
|
||||
transactionDriverControl.markRollbackOnly();
|
||||
}
|
||||
|
||||
public void invalidate() {
|
||||
valid = false;
|
||||
}
|
||||
|
||||
protected boolean allowFailedCommitToPhysicallyRollback() {
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -1,208 +0,0 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2007-2011, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.engine.transaction.internal.jdbc;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.TransactionException;
|
||||
import org.hibernate.engine.transaction.spi.AbstractTransactionImpl;
|
||||
import org.hibernate.engine.transaction.spi.IsolationDelegate;
|
||||
import org.hibernate.engine.transaction.spi.JoinStatus;
|
||||
import org.hibernate.engine.transaction.spi.LocalStatus;
|
||||
import org.hibernate.engine.transaction.spi.TransactionCoordinator;
|
||||
import org.hibernate.internal.CoreMessageLogger;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
/**
|
||||
* {@link org.hibernate.Transaction} implementation based on transaction management through a JDBC {@link java.sql.Connection}.
|
||||
* <p/>
|
||||
* This the default transaction strategy.
|
||||
*
|
||||
* @author Anton van Straaten
|
||||
* @author Gavin King
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class JdbcTransaction extends AbstractTransactionImpl {
|
||||
|
||||
private static final CoreMessageLogger LOG = Logger.getMessageLogger( CoreMessageLogger.class, JdbcTransaction.class.getName() );
|
||||
|
||||
private Connection managedConnection;
|
||||
private boolean wasInitiallyAutoCommit;
|
||||
private boolean isDriver;
|
||||
|
||||
protected JdbcTransaction(TransactionCoordinator transactionCoordinator) {
|
||||
super( transactionCoordinator );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doBegin() {
|
||||
try {
|
||||
if ( managedConnection != null ) {
|
||||
throw new TransactionException( "Already have an associated managed connection" );
|
||||
}
|
||||
managedConnection = transactionCoordinator().getJdbcCoordinator().getLogicalConnection().getConnection();
|
||||
wasInitiallyAutoCommit = managedConnection.getAutoCommit();
|
||||
LOG.debugv( "initial autocommit status: {0}", wasInitiallyAutoCommit );
|
||||
if ( wasInitiallyAutoCommit ) {
|
||||
LOG.debug( "disabling autocommit" );
|
||||
managedConnection.setAutoCommit( false );
|
||||
}
|
||||
}
|
||||
catch( SQLException e ) {
|
||||
throw new TransactionException( "JDBC begin transaction failed: ", e );
|
||||
}
|
||||
|
||||
isDriver = transactionCoordinator().takeOwnership();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void afterTransactionBegin() {
|
||||
if ( getTimeout() > 0 ) {
|
||||
transactionCoordinator().getJdbcCoordinator().setTransactionTimeOut( getTimeout() );
|
||||
}
|
||||
transactionCoordinator().sendAfterTransactionBeginNotifications( this );
|
||||
if ( isDriver ) {
|
||||
transactionCoordinator().getTransactionContext().afterTransactionBegin( this );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void beforeTransactionCommit() {
|
||||
transactionCoordinator().sendBeforeTransactionCompletionNotifications( this );
|
||||
|
||||
// basically, if we are the driver of the transaction perform a managed flush prior to
|
||||
// physically committing the transaction
|
||||
if ( isDriver && !transactionCoordinator().getTransactionContext().isFlushModeNever() ) {
|
||||
// if an exception occurs during flush, user must call rollback()
|
||||
transactionCoordinator().getTransactionContext().managedFlush();
|
||||
}
|
||||
|
||||
if ( isDriver ) {
|
||||
transactionCoordinator().getTransactionContext().beforeTransactionCompletion( this );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doCommit() throws TransactionException {
|
||||
try {
|
||||
managedConnection.commit();
|
||||
LOG.debug( "committed JDBC Connection" );
|
||||
}
|
||||
catch( SQLException e ) {
|
||||
throw new TransactionException( "unable to commit against JDBC connection", e );
|
||||
}
|
||||
finally {
|
||||
releaseManagedConnection();
|
||||
}
|
||||
}
|
||||
|
||||
private void releaseManagedConnection() {
|
||||
try {
|
||||
if ( wasInitiallyAutoCommit ) {
|
||||
LOG.debug( "re-enabling autocommit" );
|
||||
managedConnection.setAutoCommit( true );
|
||||
}
|
||||
managedConnection = null;
|
||||
}
|
||||
catch ( Exception e ) {
|
||||
LOG.debug( "Could not toggle autocommit", e );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void afterTransactionCompletion(int status) {
|
||||
transactionCoordinator().afterTransaction( this, status );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void afterAfterCompletion() {
|
||||
if ( isDriver
|
||||
&& transactionCoordinator().getTransactionContext().shouldAutoClose()
|
||||
&& !transactionCoordinator().getTransactionContext().isClosed() ) {
|
||||
try {
|
||||
transactionCoordinator().getTransactionContext().managedClose();
|
||||
}
|
||||
catch (HibernateException e) {
|
||||
LOG.unableToCloseSessionButSwallowingError( e );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void beforeTransactionRollBack() {
|
||||
// nothing to do here
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doRollback() throws TransactionException {
|
||||
try {
|
||||
managedConnection.rollback();
|
||||
LOG.debug( "rolled JDBC Connection" );
|
||||
}
|
||||
catch( SQLException e ) {
|
||||
throw new TransactionException( "unable to rollback against JDBC connection", e );
|
||||
}
|
||||
finally {
|
||||
releaseManagedConnection();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInitiator() {
|
||||
return isActive();
|
||||
}
|
||||
|
||||
@Override
|
||||
public IsolationDelegate createIsolationDelegate() {
|
||||
return new JdbcIsolationDelegate( transactionCoordinator() );
|
||||
}
|
||||
|
||||
@Override
|
||||
public JoinStatus getJoinStatus() {
|
||||
return isActive() ? JoinStatus.JOINED : JoinStatus.NOT_JOINED;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void markRollbackOnly() {
|
||||
// nothing to do here
|
||||
}
|
||||
|
||||
@Override
|
||||
public void join() {
|
||||
// nothing to do
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resetJoinStatus() {
|
||||
// nothing to do
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isActive() throws HibernateException {
|
||||
return getLocalStatus() == LocalStatus.ACTIVE;
|
||||
}
|
||||
}
|
|
@ -1,63 +0,0 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2007-2011, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.engine.transaction.internal.jdbc;
|
||||
|
||||
import org.hibernate.ConnectionReleaseMode;
|
||||
import org.hibernate.engine.transaction.spi.TransactionCoordinator;
|
||||
import org.hibernate.engine.transaction.spi.TransactionFactory;
|
||||
|
||||
/**
|
||||
* Factory for {@link org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction} instances.
|
||||
*
|
||||
* @author Anton van Straaten
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public final class JdbcTransactionFactory implements TransactionFactory<JdbcTransaction> {
|
||||
public static final String SHORT_NAME = "jdbc";
|
||||
|
||||
@Override
|
||||
public JdbcTransaction createTransaction(TransactionCoordinator transactionCoordinator) {
|
||||
return new JdbcTransaction( transactionCoordinator );
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canBeDriver() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConnectionReleaseMode getDefaultReleaseMode() {
|
||||
return ConnectionReleaseMode.ON_CLOSE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean compatibleWithJtaSynchronization() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isJoinableJtaTransaction(TransactionCoordinator transactionCoordinator, JdbcTransaction transaction) {
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -1,173 +0,0 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2007-2011, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.engine.transaction.internal.jta;
|
||||
|
||||
import javax.transaction.SystemException;
|
||||
import javax.transaction.TransactionManager;
|
||||
|
||||
import org.hibernate.TransactionException;
|
||||
import org.hibernate.engine.transaction.spi.AbstractTransactionImpl;
|
||||
import org.hibernate.engine.transaction.spi.IsolationDelegate;
|
||||
import org.hibernate.engine.transaction.spi.JoinStatus;
|
||||
import org.hibernate.engine.transaction.spi.TransactionCoordinator;
|
||||
|
||||
/**
|
||||
* Implements a transaction strategy for Container Managed Transaction (CMT) scenarios. All work is done in
|
||||
* the context of the container managed transaction.
|
||||
* <p/>
|
||||
* The term 'CMT' is potentially misleading; the pertinent point simply being that the transactions are being
|
||||
* managed by something other than the Hibernate transaction mechanism.
|
||||
* <p/>
|
||||
* Additionally, this strategy does *not* attempt to access or use the {@link javax.transaction.UserTransaction} since
|
||||
* in the actual case CMT access to the {@link javax.transaction.UserTransaction} is explicitly disallowed. Instead
|
||||
* we use the JTA {@link javax.transaction.Transaction} object obtained from the {@link TransactionManager}
|
||||
*
|
||||
* @author Gavin King
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class CMTTransaction extends AbstractTransactionImpl {
|
||||
private JoinStatus joinStatus = JoinStatus.NOT_JOINED;
|
||||
|
||||
protected CMTTransaction(TransactionCoordinator transactionCoordinator) {
|
||||
super( transactionCoordinator );
|
||||
}
|
||||
|
||||
protected TransactionManager transactionManager() {
|
||||
return jtaPlatform().retrieveTransactionManager();
|
||||
}
|
||||
|
||||
private TransactionManager getTransactionManager() {
|
||||
return transactionManager();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doBegin() {
|
||||
transactionCoordinator().pulse();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void afterTransactionBegin() {
|
||||
if ( ! transactionCoordinator().isSynchronizationRegistered() ) {
|
||||
throw new TransactionException("Could not register synchronization for container transaction");
|
||||
}
|
||||
transactionCoordinator().sendAfterTransactionBeginNotifications( this );
|
||||
transactionCoordinator().getTransactionContext().afterTransactionBegin( this );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void beforeTransactionCommit() {
|
||||
boolean flush = ! transactionCoordinator().getTransactionContext().isFlushModeNever() &&
|
||||
! transactionCoordinator().getTransactionContext().isFlushBeforeCompletionEnabled();
|
||||
if ( flush ) {
|
||||
// if an exception occurs during flush, user must call rollback()
|
||||
transactionCoordinator().getTransactionContext().managedFlush();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doCommit() {
|
||||
// nothing to do
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void beforeTransactionRollBack() {
|
||||
// nothing to do
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doRollback() {
|
||||
markRollbackOnly();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void afterTransactionCompletion(int status) {
|
||||
// nothing to do
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void afterAfterCompletion() {
|
||||
// nothing to do
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isActive() throws TransactionException {
|
||||
return JtaStatusHelper.isActive( getTransactionManager() );
|
||||
}
|
||||
|
||||
@Override
|
||||
public IsolationDelegate createIsolationDelegate() {
|
||||
return new JtaIsolationDelegate( transactionCoordinator() );
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInitiator() {
|
||||
return false; // cannot be
|
||||
}
|
||||
|
||||
@Override
|
||||
public void markRollbackOnly() {
|
||||
try {
|
||||
getTransactionManager().setRollbackOnly();
|
||||
}
|
||||
catch ( SystemException se ) {
|
||||
throw new TransactionException("Could not set transaction to rollback only", se);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void markForJoin() {
|
||||
joinStatus = JoinStatus.MARKED_FOR_JOINED;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void join() {
|
||||
if ( joinStatus != JoinStatus.MARKED_FOR_JOINED ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( JtaStatusHelper.isActive( transactionManager() ) ) {
|
||||
// register synchronization if needed
|
||||
transactionCoordinator().pulse();
|
||||
joinStatus = JoinStatus.JOINED;
|
||||
}
|
||||
else {
|
||||
joinStatus = JoinStatus.NOT_JOINED;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resetJoinStatus() {
|
||||
joinStatus = JoinStatus.NOT_JOINED;
|
||||
}
|
||||
|
||||
boolean isJoinable() {
|
||||
return ( joinStatus == JoinStatus.JOINED || joinStatus == JoinStatus.MARKED_FOR_JOINED ) &&
|
||||
JtaStatusHelper.isActive( transactionManager() );
|
||||
}
|
||||
|
||||
@Override
|
||||
public JoinStatus getJoinStatus() {
|
||||
return joinStatus;
|
||||
}
|
||||
}
|
|
@ -1,77 +0,0 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2007-2011, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.engine.transaction.internal.jta;
|
||||
|
||||
import javax.transaction.SystemException;
|
||||
|
||||
import org.hibernate.ConnectionReleaseMode;
|
||||
import org.hibernate.TransactionException;
|
||||
import org.hibernate.engine.transaction.spi.TransactionCoordinator;
|
||||
import org.hibernate.engine.transaction.spi.TransactionFactory;
|
||||
|
||||
/**
|
||||
* Factory for Container Managed Transaction (CMT) based transaction facades.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
* @author Gavin King
|
||||
*/
|
||||
public class CMTTransactionFactory implements TransactionFactory<CMTTransaction> {
|
||||
public static final String SHORT_NAME = "cmt";
|
||||
|
||||
@Override
|
||||
public CMTTransaction createTransaction(TransactionCoordinator transactionCoordinator) {
|
||||
return new CMTTransaction( transactionCoordinator );
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canBeDriver() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConnectionReleaseMode getDefaultReleaseMode() {
|
||||
return ConnectionReleaseMode.AFTER_STATEMENT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean compatibleWithJtaSynchronization() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isJoinableJtaTransaction(TransactionCoordinator transactionCoordinator, CMTTransaction transaction) {
|
||||
try {
|
||||
final int status = transactionCoordinator
|
||||
.getTransactionContext()
|
||||
.getTransactionEnvironment()
|
||||
.getJtaPlatform()
|
||||
.getCurrentStatus();
|
||||
return JtaStatusHelper.isActive( status );
|
||||
}
|
||||
catch( SystemException se ) {
|
||||
throw new TransactionException( "Unable to check transaction status", se );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,285 +0,0 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2007-2011, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.engine.transaction.internal.jta;
|
||||
|
||||
import javax.transaction.Status;
|
||||
import javax.transaction.SystemException;
|
||||
import javax.transaction.TransactionManager;
|
||||
import javax.transaction.UserTransaction;
|
||||
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.TransactionException;
|
||||
import org.hibernate.engine.transaction.spi.AbstractTransactionImpl;
|
||||
import org.hibernate.engine.transaction.spi.IsolationDelegate;
|
||||
import org.hibernate.engine.transaction.spi.JoinStatus;
|
||||
import org.hibernate.engine.transaction.spi.LocalStatus;
|
||||
import org.hibernate.engine.transaction.spi.TransactionCoordinator;
|
||||
import org.hibernate.internal.CoreLogging;
|
||||
import org.hibernate.internal.CoreMessageLogger;
|
||||
|
||||
/**
|
||||
* Implements a transaction strategy based on transaction management through a JTA {@link UserTransaction}.
|
||||
*
|
||||
* @author Gavin King
|
||||
* @author Steve Ebersole
|
||||
* @author Les Hazlewood
|
||||
*/
|
||||
public class JtaTransaction extends AbstractTransactionImpl {
|
||||
private static final CoreMessageLogger LOG = CoreLogging.messageLogger( JtaTransaction.class );
|
||||
|
||||
private UserTransaction userTransaction;
|
||||
|
||||
private boolean isInitiator;
|
||||
private boolean isDriver;
|
||||
|
||||
protected JtaTransaction(TransactionCoordinator transactionCoordinator) {
|
||||
super( transactionCoordinator );
|
||||
}
|
||||
|
||||
@SuppressWarnings( {"UnusedDeclaration"})
|
||||
public UserTransaction getUserTransaction() {
|
||||
return userTransaction;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doBegin() {
|
||||
LOG.debug( "begin" );
|
||||
|
||||
userTransaction = locateUserTransaction();
|
||||
|
||||
try {
|
||||
if ( userTransaction.getStatus() == Status.STATUS_NO_TRANSACTION ) {
|
||||
userTransaction.begin();
|
||||
isInitiator = true;
|
||||
LOG.debug( "Began a new JTA transaction" );
|
||||
}
|
||||
}
|
||||
catch ( Exception e ) {
|
||||
throw new TransactionException( "JTA transaction begin failed", e );
|
||||
}
|
||||
}
|
||||
|
||||
private UserTransaction locateUserTransaction() {
|
||||
final UserTransaction userTransaction = jtaPlatform().retrieveUserTransaction();
|
||||
if ( userTransaction == null ) {
|
||||
throw new TransactionException( "Unable to locate JTA UserTransaction" );
|
||||
}
|
||||
return userTransaction;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void afterTransactionBegin() {
|
||||
transactionCoordinator().pulse();
|
||||
|
||||
if ( !transactionCoordinator().isSynchronizationRegistered() ) {
|
||||
isDriver = transactionCoordinator().takeOwnership();
|
||||
}
|
||||
|
||||
applyTimeout();
|
||||
transactionCoordinator().sendAfterTransactionBeginNotifications( this );
|
||||
transactionCoordinator().getTransactionContext().afterTransactionBegin( this );
|
||||
}
|
||||
|
||||
private void applyTimeout() {
|
||||
if ( getTimeout() > 0 ) {
|
||||
if ( userTransaction != null ) {
|
||||
try {
|
||||
userTransaction.setTransactionTimeout( getTimeout() );
|
||||
}
|
||||
catch ( SystemException e ) {
|
||||
throw new TransactionException( "Unable to apply requested transaction timeout", e );
|
||||
}
|
||||
}
|
||||
else {
|
||||
LOG.debug( "Unable to apply requested transaction timeout; no UserTransaction. Will try later" );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void beforeTransactionCommit() {
|
||||
transactionCoordinator().sendBeforeTransactionCompletionNotifications( this );
|
||||
|
||||
final boolean flush = ! transactionCoordinator().getTransactionContext().isFlushModeNever() &&
|
||||
( isDriver || ! transactionCoordinator().getTransactionContext().isFlushBeforeCompletionEnabled() );
|
||||
|
||||
if ( flush ) {
|
||||
// if an exception occurs during flush, user must call rollback()
|
||||
transactionCoordinator().getTransactionContext().managedFlush();
|
||||
}
|
||||
|
||||
if ( isDriver && isInitiator ) {
|
||||
transactionCoordinator().getTransactionContext().beforeTransactionCompletion( this );
|
||||
}
|
||||
|
||||
closeIfRequired();
|
||||
}
|
||||
|
||||
private void closeIfRequired() throws HibernateException {
|
||||
final boolean close = isDriver &&
|
||||
transactionCoordinator().getTransactionContext().shouldAutoClose() &&
|
||||
! transactionCoordinator().getTransactionContext().isClosed();
|
||||
if ( close ) {
|
||||
transactionCoordinator().getTransactionContext().managedClose();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doCommit() {
|
||||
try {
|
||||
if ( isInitiator ) {
|
||||
userTransaction.commit();
|
||||
LOG.debug( "Committed JTA UserTransaction" );
|
||||
}
|
||||
}
|
||||
catch ( Exception e ) {
|
||||
throw new TransactionException( "JTA commit failed: ", e );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void afterTransactionCompletion(int status) {
|
||||
// nothing to do
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void afterAfterCompletion() {
|
||||
// this method is a noop if there is a Synchronization!
|
||||
try {
|
||||
if ( isDriver ) {
|
||||
if ( !isInitiator ) {
|
||||
LOG.setManagerLookupClass();
|
||||
}
|
||||
try {
|
||||
transactionCoordinator().afterTransaction( this, userTransaction.getStatus() );
|
||||
}
|
||||
catch (SystemException e) {
|
||||
throw new TransactionException( "Unable to determine UserTransaction status", e );
|
||||
}
|
||||
}
|
||||
}
|
||||
finally {
|
||||
isInitiator = false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void beforeTransactionRollBack() {
|
||||
// nothing to do
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doRollback() {
|
||||
try {
|
||||
if ( isInitiator ) {
|
||||
// failed commits automatically rollback the transaction per JTA spec
|
||||
if ( getLocalStatus() != LocalStatus.FAILED_COMMIT ) {
|
||||
userTransaction.rollback();
|
||||
LOG.debug( "Rolled back JTA UserTransaction" );
|
||||
}
|
||||
}
|
||||
else {
|
||||
markRollbackOnly();
|
||||
}
|
||||
}
|
||||
catch ( Exception e ) {
|
||||
throw new TransactionException( "JTA rollback failed", e );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void markRollbackOnly() {
|
||||
LOG.trace( "Marking transaction for rollback only" );
|
||||
try {
|
||||
if ( userTransaction == null ) {
|
||||
userTransaction = locateUserTransaction();
|
||||
}
|
||||
userTransaction.setRollbackOnly();
|
||||
LOG.debug( "set JTA UserTransaction to rollback only" );
|
||||
}
|
||||
catch (SystemException e) {
|
||||
LOG.debug( "Unable to mark transaction for rollback only", e );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public IsolationDelegate createIsolationDelegate() {
|
||||
return new JtaIsolationDelegate( transactionCoordinator() );
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInitiator() {
|
||||
return isInitiator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isActive() throws HibernateException {
|
||||
if ( getLocalStatus() != LocalStatus.ACTIVE ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final int status;
|
||||
try {
|
||||
status = userTransaction.getStatus();
|
||||
}
|
||||
catch ( SystemException se ) {
|
||||
throw new TransactionException( "Could not determine transaction status: ", se );
|
||||
}
|
||||
return JtaStatusHelper.isActive( status );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTimeout(int seconds) {
|
||||
super.setTimeout( seconds );
|
||||
applyTimeout();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void join() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resetJoinStatus() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public JoinStatus getJoinStatus() {
|
||||
// if we already have the UserTransaction cached locally, use it to avoid JNDI look ups
|
||||
if ( this.userTransaction != null ) {
|
||||
return JtaStatusHelper.isActive( this.userTransaction ) ? JoinStatus.JOINED : JoinStatus.NOT_JOINED;
|
||||
}
|
||||
|
||||
// Otherwise, try to use the TransactionManager since it is generally cached
|
||||
TransactionManager transactionManager = jtaPlatform().retrieveTransactionManager();
|
||||
if ( transactionManager != null ) {
|
||||
return JtaStatusHelper.isActive( transactionManager ) ? JoinStatus.JOINED : JoinStatus.NOT_JOINED;
|
||||
}
|
||||
|
||||
// Finally, look up the UserTransaction
|
||||
UserTransaction userTransaction = jtaPlatform().retrieveUserTransaction();
|
||||
return userTransaction != null && JtaStatusHelper.isActive( userTransaction )
|
||||
? JoinStatus.JOINED
|
||||
: JoinStatus.NOT_JOINED;
|
||||
}
|
||||
}
|
|
@ -1,104 +0,0 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2007-2011, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.engine.transaction.internal.jta;
|
||||
|
||||
import javax.transaction.SystemException;
|
||||
import javax.transaction.UserTransaction;
|
||||
|
||||
import org.hibernate.ConnectionReleaseMode;
|
||||
import org.hibernate.TransactionException;
|
||||
import org.hibernate.engine.transaction.jta.platform.spi.JtaPlatform;
|
||||
import org.hibernate.engine.transaction.spi.TransactionCoordinator;
|
||||
import org.hibernate.engine.transaction.spi.TransactionFactory;
|
||||
|
||||
/**
|
||||
* Factory for {@link JtaTransaction} instances.
|
||||
*
|
||||
* @author Gavin King
|
||||
* @author Steve Ebersole
|
||||
* @author Les Hazlewood
|
||||
*/
|
||||
public class JtaTransactionFactory implements TransactionFactory<JtaTransaction> {
|
||||
public static final String SHORT_NAME = "jta";
|
||||
|
||||
@Override
|
||||
public JtaTransaction createTransaction(TransactionCoordinator transactionCoordinator) {
|
||||
return new JtaTransaction( transactionCoordinator );
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canBeDriver() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConnectionReleaseMode getDefaultReleaseMode() {
|
||||
return ConnectionReleaseMode.AFTER_STATEMENT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean compatibleWithJtaSynchronization() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isJoinableJtaTransaction(TransactionCoordinator transactionCoordinator, JtaTransaction transaction) {
|
||||
try {
|
||||
// Essentially:
|
||||
// 1) If we have a local (Hibernate) transaction in progress
|
||||
// and it already has the UserTransaction cached, use that
|
||||
// UserTransaction to determine the status.
|
||||
// 2) If a transaction manager has been located, use
|
||||
// that transaction manager to determine the status.
|
||||
// 3) Finally, as the last resort, try to lookup the
|
||||
// UserTransaction via JNDI and use that to determine the
|
||||
// status.
|
||||
if ( transaction != null ) {
|
||||
UserTransaction ut = transaction.getUserTransaction();
|
||||
if ( ut != null ) {
|
||||
return JtaStatusHelper.isActive( ut );
|
||||
}
|
||||
}
|
||||
|
||||
final JtaPlatform jtaPlatform = transactionCoordinator
|
||||
.getTransactionContext()
|
||||
.getTransactionEnvironment()
|
||||
.getJtaPlatform();
|
||||
if ( jtaPlatform == null ) {
|
||||
throw new TransactionException( "Unable to check transaction status" );
|
||||
}
|
||||
if ( jtaPlatform.retrieveTransactionManager() != null ) {
|
||||
return JtaStatusHelper.isActive( jtaPlatform.retrieveTransactionManager().getStatus() );
|
||||
}
|
||||
else {
|
||||
final UserTransaction ut = jtaPlatform.retrieveUserTransaction();
|
||||
return ut != null && JtaStatusHelper.isActive( ut );
|
||||
}
|
||||
}
|
||||
catch ( SystemException se ) {
|
||||
throw new TransactionException( "Unable to check transaction status", se );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,251 +0,0 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2011, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.engine.transaction.spi;
|
||||
|
||||
import javax.transaction.Status;
|
||||
import javax.transaction.Synchronization;
|
||||
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.TransactionException;
|
||||
import org.hibernate.engine.transaction.jta.platform.spi.JtaPlatform;
|
||||
import org.hibernate.internal.CoreLogging;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
/**
|
||||
* Abstract support for creating {@link TransactionImplementor transaction} implementations
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public abstract class AbstractTransactionImpl implements TransactionImplementor {
|
||||
private static final Logger LOG = CoreLogging.logger( AbstractTransactionImpl.class );
|
||||
|
||||
private final TransactionCoordinator transactionCoordinator;
|
||||
|
||||
private boolean valid = true;
|
||||
|
||||
private LocalStatus localStatus = LocalStatus.NOT_ACTIVE;
|
||||
private int timeout = -1;
|
||||
|
||||
protected AbstractTransactionImpl(TransactionCoordinator transactionCoordinator) {
|
||||
this.transactionCoordinator = transactionCoordinator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invalidate() {
|
||||
valid = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform the actual steps of beginning a transaction according to the strategy.
|
||||
*
|
||||
* @throws org.hibernate.TransactionException Indicates a problem beginning the transaction
|
||||
*/
|
||||
protected abstract void doBegin();
|
||||
|
||||
/**
|
||||
* Perform the actual steps of committing a transaction according to the strategy.
|
||||
*
|
||||
* @throws org.hibernate.TransactionException Indicates a problem committing the transaction
|
||||
*/
|
||||
protected abstract void doCommit();
|
||||
|
||||
/**
|
||||
* Perform the actual steps of rolling back a transaction according to the strategy.
|
||||
*
|
||||
* @throws org.hibernate.TransactionException Indicates a problem rolling back the transaction
|
||||
*/
|
||||
protected abstract void doRollback();
|
||||
|
||||
protected abstract void afterTransactionBegin();
|
||||
|
||||
protected abstract void beforeTransactionCommit();
|
||||
|
||||
protected abstract void beforeTransactionRollBack();
|
||||
|
||||
protected abstract void afterTransactionCompletion(int status);
|
||||
|
||||
protected abstract void afterAfterCompletion();
|
||||
|
||||
/**
|
||||
* Provide subclasses with access to the transaction coordinator.
|
||||
*
|
||||
* @return This transaction's context.
|
||||
*/
|
||||
protected TransactionCoordinator transactionCoordinator() {
|
||||
return transactionCoordinator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide subclasses with convenient access to the configured {@link JtaPlatform}
|
||||
*
|
||||
* @return The {@link org.hibernate.engine.transaction.jta.platform.spi.JtaPlatform}
|
||||
*/
|
||||
protected JtaPlatform jtaPlatform() {
|
||||
return transactionCoordinator().getTransactionContext().getTransactionEnvironment().getJtaPlatform();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerSynchronization(Synchronization synchronization) {
|
||||
transactionCoordinator().getSynchronizationRegistry().registerSynchronization( synchronization );
|
||||
}
|
||||
|
||||
@Override
|
||||
public LocalStatus getLocalStatus() {
|
||||
return localStatus;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isActive() {
|
||||
return localStatus == LocalStatus.ACTIVE && doExtendedActiveCheck();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isParticipating() {
|
||||
return getJoinStatus() == JoinStatus.JOINED && isActive();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean wasCommitted() {
|
||||
return localStatus == LocalStatus.COMMITTED;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean wasRolledBack() throws HibernateException {
|
||||
return localStatus == LocalStatus.ROLLED_BACK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Active has been checked against local state. Perform any needed checks against resource transactions.
|
||||
*
|
||||
* @return {@code true} if the extended active check checks out as well; false otherwise.
|
||||
*/
|
||||
protected boolean doExtendedActiveCheck() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void begin() throws HibernateException {
|
||||
if ( !valid ) {
|
||||
throw new TransactionException( "Transaction instance is no longer valid" );
|
||||
}
|
||||
if ( localStatus == LocalStatus.ACTIVE ) {
|
||||
throw new TransactionException( "nested transactions not supported" );
|
||||
}
|
||||
if ( localStatus != LocalStatus.NOT_ACTIVE ) {
|
||||
throw new TransactionException( "reuse of Transaction instances not supported" );
|
||||
}
|
||||
|
||||
LOG.debug( "begin" );
|
||||
|
||||
doBegin();
|
||||
|
||||
localStatus = LocalStatus.ACTIVE;
|
||||
|
||||
afterTransactionBegin();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void commit() throws HibernateException {
|
||||
if ( localStatus != LocalStatus.ACTIVE ) {
|
||||
throw new TransactionException( "Transaction not successfully started" );
|
||||
}
|
||||
|
||||
LOG.debug( "committing" );
|
||||
|
||||
beforeTransactionCommit();
|
||||
|
||||
try {
|
||||
doCommit();
|
||||
localStatus = LocalStatus.COMMITTED;
|
||||
afterTransactionCompletion( Status.STATUS_COMMITTED );
|
||||
}
|
||||
catch (Exception e) {
|
||||
localStatus = LocalStatus.FAILED_COMMIT;
|
||||
afterTransactionCompletion( Status.STATUS_UNKNOWN );
|
||||
throw new TransactionException( "commit failed", e );
|
||||
}
|
||||
finally {
|
||||
invalidate();
|
||||
afterAfterCompletion();
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean allowFailedCommitToPhysicallyRollback() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rollback() throws HibernateException {
|
||||
if ( localStatus != LocalStatus.ACTIVE && localStatus != LocalStatus.FAILED_COMMIT ) {
|
||||
throw new TransactionException( "Transaction not successfully started" );
|
||||
}
|
||||
|
||||
LOG.debug( "rolling back" );
|
||||
|
||||
beforeTransactionRollBack();
|
||||
|
||||
if ( localStatus != LocalStatus.FAILED_COMMIT || allowFailedCommitToPhysicallyRollback() ) {
|
||||
try {
|
||||
doRollback();
|
||||
localStatus = LocalStatus.ROLLED_BACK;
|
||||
afterTransactionCompletion( Status.STATUS_ROLLEDBACK );
|
||||
}
|
||||
catch (Exception e) {
|
||||
afterTransactionCompletion( Status.STATUS_UNKNOWN );
|
||||
throw new TransactionException( "rollback failed", e );
|
||||
}
|
||||
finally {
|
||||
invalidate();
|
||||
afterAfterCompletion();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTimeout(int seconds) {
|
||||
timeout = seconds;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTimeout() {
|
||||
return timeout;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void markForJoin() {
|
||||
// generally speaking this is no-op
|
||||
}
|
||||
|
||||
@Override
|
||||
public void join() {
|
||||
// generally speaking this is no-op
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resetJoinStatus() {
|
||||
// generally speaking this is no-op
|
||||
}
|
||||
}
|
|
@ -1,130 +0,0 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2011, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.engine.transaction.spi;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.hibernate.ConnectionReleaseMode;
|
||||
import org.hibernate.engine.jdbc.connections.spi.JdbcConnectionAccess;
|
||||
|
||||
/**
|
||||
* Access to services needed in the context of processing transaction requests.
|
||||
* <p/>
|
||||
* The context is roughly speaking equivalent to the Hibernate session, as opposed to the {@link TransactionEnvironment}
|
||||
* which is roughly equivalent to the Hibernate session factory
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface TransactionContext extends Serializable {
|
||||
/**
|
||||
* Obtain the {@link TransactionEnvironment} associated with this context.
|
||||
*
|
||||
* @return The transaction environment.
|
||||
*/
|
||||
public TransactionEnvironment getTransactionEnvironment();
|
||||
|
||||
/**
|
||||
* Get the mode for releasing JDBC connection in effect for ths context.
|
||||
*
|
||||
* @return The connection release mode.
|
||||
*/
|
||||
public ConnectionReleaseMode getConnectionReleaseMode();
|
||||
|
||||
/**
|
||||
* Should transactions be auto joined? Generally this is only a concern for CMT transactions. The default
|
||||
* should be to auto join. JPA defines an explicit operation for joining a CMT transaction.
|
||||
*
|
||||
* @return Should we automatically join transactions
|
||||
*/
|
||||
public boolean shouldAutoJoinTransaction();
|
||||
|
||||
/**
|
||||
* Should session automatically be closed after transaction completion in this context?
|
||||
*
|
||||
* @return {@literal true}/{@literal false} appropriately.
|
||||
*/
|
||||
public boolean isAutoCloseSessionEnabled();
|
||||
|
||||
/**
|
||||
* Is this context already closed?
|
||||
*
|
||||
* @return {@literal true}/{@literal false} appropriately.
|
||||
*/
|
||||
public boolean isClosed();
|
||||
|
||||
/**
|
||||
* Should flushes only happen manually for this context?
|
||||
*
|
||||
* @return {@literal true}/{@literal false} appropriately.
|
||||
*/
|
||||
public boolean isFlushModeNever();
|
||||
|
||||
/**
|
||||
* Should before transaction completion processing perform a flush when initiated from JTA synchronization for this
|
||||
* context?
|
||||
*
|
||||
* @return {@literal true}/{@literal false} appropriately.
|
||||
*/
|
||||
public boolean isFlushBeforeCompletionEnabled();
|
||||
|
||||
/**
|
||||
* Perform a managed flush.
|
||||
*/
|
||||
public void managedFlush();
|
||||
|
||||
/**
|
||||
* Should JTA synchronization processing perform a automatic close (call to {@link #managedClose} for this
|
||||
* context?
|
||||
*
|
||||
* @return {@literal true}/{@literal false} appropriately.
|
||||
*/
|
||||
public boolean shouldAutoClose();
|
||||
|
||||
/**
|
||||
* Perform a managed close.
|
||||
*/
|
||||
public void managedClose();
|
||||
|
||||
public void afterTransactionBegin(TransactionImplementor hibernateTransaction);
|
||||
|
||||
public void beforeTransactionCompletion(TransactionImplementor hibernateTransaction);
|
||||
|
||||
public void afterTransactionCompletion(TransactionImplementor hibernateTransaction, boolean successful);
|
||||
|
||||
public String onPrepareStatement(String sql);
|
||||
|
||||
public JdbcConnectionAccess getJdbcConnectionAccess();
|
||||
|
||||
public void startPrepareStatement();
|
||||
|
||||
public void endPrepareStatement();
|
||||
|
||||
public void startStatementExecution();
|
||||
|
||||
public void endStatementExecution();
|
||||
|
||||
public void startBatchExecution();
|
||||
|
||||
public void endBatchExecution();
|
||||
}
|
|
@ -1,146 +0,0 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2011, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.engine.transaction.spi;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.sql.Connection;
|
||||
|
||||
import org.hibernate.engine.jdbc.spi.JdbcCoordinator;
|
||||
import org.hibernate.engine.transaction.synchronization.spi.SynchronizationCallbackCoordinator;
|
||||
|
||||
/**
|
||||
* Acts as the coordinator between the Hibernate engine and physical transactions.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface TransactionCoordinator extends Serializable {
|
||||
/**
|
||||
* Retrieves the context in which this coordinator operates.
|
||||
*
|
||||
* @return The context of the coordinator
|
||||
*/
|
||||
public TransactionContext getTransactionContext();
|
||||
|
||||
/**
|
||||
* Retrieves the JDBC coordinator currently operating within this transaction coordinator.
|
||||
*
|
||||
* @return The JDBC coordinator.
|
||||
*/
|
||||
public JdbcCoordinator getJdbcCoordinator();
|
||||
|
||||
/**
|
||||
* Get the Hibernate transaction facade object currently associated with this coordinator.
|
||||
*
|
||||
* @return The current Hibernate transaction.
|
||||
*/
|
||||
public TransactionImplementor getTransaction();
|
||||
|
||||
/**
|
||||
* Obtain the {@link javax.transaction.Synchronization} registry associated with this coordinator.
|
||||
*
|
||||
* @return The registry
|
||||
*/
|
||||
public SynchronizationRegistry getSynchronizationRegistry();
|
||||
|
||||
/**
|
||||
* Adds an observer to the coordinator.
|
||||
* <p/>
|
||||
* Unlike synchronizations added to the {@link #getSynchronizationRegistry() registry}, observers are not to be
|
||||
* cleared on transaction completion.
|
||||
*
|
||||
* @param observer The observer to add.
|
||||
*/
|
||||
public void addObserver(TransactionObserver observer);
|
||||
|
||||
/**
|
||||
* Removed an observer from the coordinator.
|
||||
*
|
||||
* @param observer The observer to remove.
|
||||
*/
|
||||
public void removeObserver(TransactionObserver observer);
|
||||
|
||||
/**
|
||||
* Can we join to the underlying transaction?
|
||||
*
|
||||
* @return {@literal true} if the underlying transaction can be joined or is already joined; {@literal false}
|
||||
* otherwise.
|
||||
*
|
||||
* @see TransactionFactory#isJoinableJtaTransaction(TransactionCoordinator, TransactionImplementor)
|
||||
*/
|
||||
public boolean isTransactionJoinable();
|
||||
|
||||
/**
|
||||
* Is the underlying transaction already joined?
|
||||
*
|
||||
* @return {@literal true} if the underlying transaction is already joined; {@literal false} otherwise.
|
||||
*/
|
||||
public boolean isTransactionJoined();
|
||||
|
||||
/**
|
||||
* Reset the transaction's join status.
|
||||
*/
|
||||
public void resetJoinStatus();
|
||||
|
||||
/**
|
||||
* Are we "in" an active and joined transaction
|
||||
*
|
||||
* @return {@literal true} if there is currently a transaction in progress; {@literal false} otherwise.
|
||||
*/
|
||||
public boolean isTransactionInProgress();
|
||||
|
||||
/**
|
||||
* Attempts to register JTA synchronization if possible and needed.
|
||||
*/
|
||||
public void pulse();
|
||||
|
||||
/**
|
||||
* Close the transaction context, returning any user supplied connection from the underlying JDBC coordinator.
|
||||
*
|
||||
* @return The user supplied connection (if one).
|
||||
*/
|
||||
public Connection close();
|
||||
|
||||
/**
|
||||
* Performs actions needed after execution of a non-transactional query.
|
||||
*
|
||||
* @param success Was the query successfully performed
|
||||
*/
|
||||
public void afterNonTransactionalQuery(boolean success);
|
||||
|
||||
public void setRollbackOnly();
|
||||
|
||||
public SynchronizationCallbackCoordinator getSynchronizationCallbackCoordinator();
|
||||
|
||||
public boolean isSynchronizationRegistered();
|
||||
public boolean takeOwnership();
|
||||
|
||||
public void afterTransaction(TransactionImplementor hibernateTransaction, int status);
|
||||
|
||||
public void sendAfterTransactionBeginNotifications(TransactionImplementor hibernateTransaction);
|
||||
public void sendBeforeTransactionCompletionNotifications(TransactionImplementor hibernateTransaction);
|
||||
public void sendAfterTransactionCompletionNotifications(TransactionImplementor hibernateTransaction, int status);
|
||||
|
||||
public boolean isActive();
|
||||
|
||||
}
|
|
@ -1,83 +0,0 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2011, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.engine.transaction.spi;
|
||||
|
||||
import org.hibernate.ConnectionReleaseMode;
|
||||
import org.hibernate.service.Service;
|
||||
|
||||
/**
|
||||
* Contract for transaction creation, as well as providing metadata and contextual information about that creation.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface TransactionFactory<T extends TransactionImplementor> extends Service {
|
||||
/**
|
||||
* Construct a transaction instance compatible with this strategy.
|
||||
*
|
||||
* @param coordinator The coordinator for this transaction
|
||||
*
|
||||
* @return The appropriate transaction instance.
|
||||
*
|
||||
* @throws org.hibernate.HibernateException Indicates a problem constructing the transaction.
|
||||
*/
|
||||
public T createTransaction(TransactionCoordinator coordinator);
|
||||
|
||||
/**
|
||||
* Can the transactions created from this strategy act as the driver? In other words can the user actually manage
|
||||
* transactions with this strategy?
|
||||
*
|
||||
* @return {@literal true} if the transaction strategy represented by this factory can act as the driver callback;
|
||||
* {@literal false} otherwise.
|
||||
*/
|
||||
public boolean canBeDriver();
|
||||
|
||||
/**
|
||||
* Should we attempt to register JTA transaction {@link javax.transaction.Synchronization synchronizations}.
|
||||
* <p/>
|
||||
* In other words, is this strategy JTA-based?
|
||||
*
|
||||
* @return {@literal true} if the transaction strategy represented by this factory is compatible with registering
|
||||
* {@link javax.transaction.Synchronization synchronizations}; {@literal false} otherwise.
|
||||
*/
|
||||
public boolean compatibleWithJtaSynchronization();
|
||||
|
||||
/**
|
||||
* Can the underlying transaction represented by the passed Hibernate {@link TransactionImplementor} be joined?
|
||||
*
|
||||
* @param transactionCoordinator The transaction coordinator
|
||||
* @param transaction The current Hibernate transaction
|
||||
*
|
||||
* @return {@literal true} is the transaction can be joined; {@literal false} otherwise.
|
||||
*/
|
||||
public boolean isJoinableJtaTransaction(TransactionCoordinator transactionCoordinator, T transaction);
|
||||
|
||||
/**
|
||||
* Get the default connection release mode.
|
||||
*
|
||||
* @return The default release mode associated with this strategy
|
||||
*/
|
||||
public ConnectionReleaseMode getDefaultReleaseMode();
|
||||
|
||||
}
|
||||
|
|
@ -31,27 +31,22 @@ package org.hibernate.engine.transaction.spi;
|
|||
public interface TransactionObserver {
|
||||
/**
|
||||
* Callback for processing the beginning of a transaction.
|
||||
*
|
||||
* <p/>
|
||||
* Do not rely on this being called as the transaction mat be started in a manner other than through the
|
||||
* {@link org.hibernate.Transaction} API.
|
||||
*
|
||||
* @param transaction The Hibernate transaction
|
||||
*/
|
||||
public void afterBegin(TransactionImplementor transaction);
|
||||
public void afterBegin();
|
||||
|
||||
/**
|
||||
* Callback for processing the initial phase of transaction completion.
|
||||
*
|
||||
* @param transaction The Hibernate transaction
|
||||
*/
|
||||
public void beforeCompletion(TransactionImplementor transaction);
|
||||
public void beforeCompletion();
|
||||
|
||||
/**
|
||||
* Callback for processing the last phase of transaction completion.
|
||||
*
|
||||
* @param successful Was the transaction successful?
|
||||
* @param transaction The Hibernate transaction
|
||||
*/
|
||||
public void afterCompletion(boolean successful, TransactionImplementor transaction);
|
||||
public void afterCompletion(boolean successful);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,194 +0,0 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2013, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.engine.transaction.synchronization.internal;
|
||||
|
||||
import javax.transaction.SystemException;
|
||||
|
||||
import org.hibernate.TransactionException;
|
||||
import org.hibernate.engine.transaction.internal.jta.JtaStatusHelper;
|
||||
import org.hibernate.engine.transaction.spi.TransactionContext;
|
||||
import org.hibernate.engine.transaction.spi.TransactionCoordinator;
|
||||
import org.hibernate.engine.transaction.synchronization.spi.AfterCompletionAction;
|
||||
import org.hibernate.engine.transaction.synchronization.spi.ExceptionMapper;
|
||||
import org.hibernate.engine.transaction.synchronization.spi.ManagedFlushChecker;
|
||||
import org.hibernate.engine.transaction.synchronization.spi.SynchronizationCallbackCoordinator;
|
||||
import org.hibernate.internal.CoreLogging;
|
||||
import org.hibernate.internal.CoreMessageLogger;
|
||||
|
||||
/**
|
||||
* Manages callbacks from the {@link javax.transaction.Synchronization} registered by Hibernate.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class SynchronizationCallbackCoordinatorNonTrackingImpl implements SynchronizationCallbackCoordinator {
|
||||
private static final CoreMessageLogger LOG = CoreLogging.messageLogger(
|
||||
SynchronizationCallbackCoordinatorNonTrackingImpl.class
|
||||
);
|
||||
|
||||
private final TransactionCoordinator transactionCoordinator;
|
||||
|
||||
private ManagedFlushChecker managedFlushChecker;
|
||||
private AfterCompletionAction afterCompletionAction;
|
||||
private ExceptionMapper exceptionMapper;
|
||||
|
||||
public SynchronizationCallbackCoordinatorNonTrackingImpl(TransactionCoordinator transactionCoordinator) {
|
||||
this.transactionCoordinator = transactionCoordinator;
|
||||
reset();
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
managedFlushChecker = STANDARD_MANAGED_FLUSH_CHECKER;
|
||||
exceptionMapper = STANDARD_EXCEPTION_MAPPER;
|
||||
afterCompletionAction = STANDARD_AFTER_COMPLETION_ACTION;
|
||||
}
|
||||
|
||||
protected final TransactionCoordinator transactionCoordinator() {
|
||||
return transactionCoordinator;
|
||||
}
|
||||
|
||||
private TransactionContext transactionContext() {
|
||||
return transactionCoordinator.getTransactionContext();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setManagedFlushChecker(ManagedFlushChecker managedFlushChecker) {
|
||||
this.managedFlushChecker = managedFlushChecker;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setExceptionMapper(ExceptionMapper exceptionMapper) {
|
||||
this.exceptionMapper = exceptionMapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAfterCompletionAction(AfterCompletionAction afterCompletionAction) {
|
||||
this.afterCompletionAction = afterCompletionAction;
|
||||
}
|
||||
|
||||
// sync callbacks ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
@Override
|
||||
public void beforeCompletion() {
|
||||
LOG.trace( "Transaction before completion callback" );
|
||||
|
||||
if ( !transactionCoordinator.isActive() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
boolean flush;
|
||||
try {
|
||||
final int status = transactionCoordinator.getTransactionContext().getTransactionEnvironment()
|
||||
.getJtaPlatform().getCurrentStatus();
|
||||
flush = managedFlushChecker.shouldDoManagedFlush( transactionCoordinator, status );
|
||||
}
|
||||
catch ( SystemException se ) {
|
||||
setRollbackOnly();
|
||||
throw exceptionMapper.mapStatusCheckFailure(
|
||||
"could not determine transaction status in beforeCompletion()", se );
|
||||
}
|
||||
|
||||
try {
|
||||
if ( flush ) {
|
||||
LOG.trace( "Automatically flushing session" );
|
||||
transactionCoordinator.getTransactionContext().managedFlush();
|
||||
}
|
||||
}
|
||||
catch ( RuntimeException re ) {
|
||||
setRollbackOnly();
|
||||
throw exceptionMapper.mapManagedFlushFailure( "error during managed flush", re );
|
||||
}
|
||||
finally {
|
||||
transactionCoordinator.sendBeforeTransactionCompletionNotifications( null );
|
||||
transactionCoordinator.getTransactionContext().beforeTransactionCompletion( null );
|
||||
}
|
||||
}
|
||||
|
||||
private void setRollbackOnly() {
|
||||
transactionCoordinator.setRollbackOnly();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterCompletion(int status) {
|
||||
doAfterCompletion( status );
|
||||
}
|
||||
|
||||
protected void doAfterCompletion(int status) {
|
||||
LOG.tracef( "Starting transaction afterCompletion callback [status=%s]", status );
|
||||
if ( !transactionCoordinator.isActive() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
afterCompletionAction.doAction( transactionCoordinator, status );
|
||||
transactionCoordinator.afterTransaction( null, status );
|
||||
}
|
||||
finally {
|
||||
reset();
|
||||
if ( transactionContext().shouldAutoClose() && !transactionContext().isClosed() ) {
|
||||
LOG.trace( "Automatically closing session" );
|
||||
transactionContext().managedClose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void synchronizationRegistered() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processAnyDelayedAfterCompletion() {
|
||||
}
|
||||
|
||||
private static final ManagedFlushChecker STANDARD_MANAGED_FLUSH_CHECKER = new ManagedFlushChecker() {
|
||||
@Override
|
||||
public boolean shouldDoManagedFlush(TransactionCoordinator coordinator, int jtaStatus) {
|
||||
return !coordinator.getTransactionContext().isClosed()
|
||||
&& !coordinator.getTransactionContext().isFlushModeNever()
|
||||
&& coordinator.getTransactionContext().isFlushBeforeCompletionEnabled()
|
||||
&& !JtaStatusHelper.isRollback( jtaStatus );
|
||||
}
|
||||
};
|
||||
|
||||
private static final ExceptionMapper STANDARD_EXCEPTION_MAPPER = new ExceptionMapper() {
|
||||
@Override
|
||||
public RuntimeException mapStatusCheckFailure(String message, SystemException systemException) {
|
||||
LOG.error( LOG.unableToDetermineTransactionStatus(), systemException );
|
||||
return new TransactionException( "could not determine transaction status in beforeCompletion()",
|
||||
systemException );
|
||||
}
|
||||
|
||||
@Override
|
||||
public RuntimeException mapManagedFlushFailure(String message, RuntimeException failure) {
|
||||
LOG.unableToPerformManagedFlush( failure.getMessage() );
|
||||
return failure;
|
||||
}
|
||||
};
|
||||
|
||||
private static final AfterCompletionAction STANDARD_AFTER_COMPLETION_ACTION = new AfterCompletionAction() {
|
||||
@Override
|
||||
public void doAction(TransactionCoordinator transactionCoordinator, int status) {
|
||||
// nothing to do by default.
|
||||
}
|
||||
};
|
||||
}
|
|
@ -1,55 +0,0 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2011, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.engine.transaction.synchronization.spi;
|
||||
|
||||
import java.io.Serializable;
|
||||
import javax.transaction.SystemException;
|
||||
|
||||
/**
|
||||
* A pluggable strategy for defining how the {@link javax.transaction.Synchronization} registered by Hibernate handles
|
||||
* exceptions.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface ExceptionMapper extends Serializable {
|
||||
/**
|
||||
* Map a JTA {@link javax.transaction.SystemException} to the appropriate runtime-based exception.
|
||||
*
|
||||
* @param message The message to use for the returned exception
|
||||
* @param systemException The causal exception
|
||||
*
|
||||
* @return The appropriate exception to throw
|
||||
*/
|
||||
public RuntimeException mapStatusCheckFailure(String message, SystemException systemException);
|
||||
|
||||
/**
|
||||
* Map an exception encountered during a managed flush to the appropriate runtime-based exception.
|
||||
*
|
||||
* @param message The message to use for the returned exception
|
||||
* @param failure The causal exception
|
||||
*
|
||||
* @return The appropriate exception to throw
|
||||
*/
|
||||
public RuntimeException mapManagedFlushFailure(String message, RuntimeException failure);
|
||||
}
|
|
@ -342,7 +342,7 @@ public abstract class AbstractFlushingEventListener implements Serializable {
|
|||
// lazy collections during their processing.
|
||||
// For more information, see HHH-2763
|
||||
try {
|
||||
session.getTransactionCoordinator().getJdbcCoordinator().flushBeginning();
|
||||
session.getJdbcCoordinator().flushBeginning();
|
||||
session.getPersistenceContext().setFlushing( true );
|
||||
// we need to lock the collection caches before executing entity inserts/updates in order to
|
||||
// account for bi-directional associations
|
||||
|
@ -351,7 +351,7 @@ public abstract class AbstractFlushingEventListener implements Serializable {
|
|||
}
|
||||
finally {
|
||||
session.getPersistenceContext().setFlushing( false );
|
||||
session.getTransactionCoordinator().getJdbcCoordinator().flushEnding();
|
||||
session.getJdbcCoordinator().flushEnding();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -243,7 +243,7 @@ public abstract class AbstractSaveEventListener extends AbstractReassociateEvent
|
|||
|
||||
Serializable id = key == null ? null : key.getIdentifier();
|
||||
|
||||
boolean inTxn = source.getTransactionCoordinator().isTransactionInProgress();
|
||||
boolean inTxn = source.isTransactionInProgress();
|
||||
boolean shouldDelayIdentityInserts = !inTxn && !requiresImmediateIdAccess;
|
||||
|
||||
// Put a placeholder in entries, so we don't recurse back and try to save() the
|
||||
|
|
|
@ -93,7 +93,7 @@ public class BasicExecutor implements StatementExecutor {
|
|||
|
||||
try {
|
||||
try {
|
||||
st = session.getTransactionCoordinator().getJdbcCoordinator().getStatementPreparer().prepareStatement( sql, false );
|
||||
st = session.getJdbcCoordinator().getStatementPreparer().prepareStatement( sql, false );
|
||||
Iterator paramSpecItr = parameterSpecifications.iterator();
|
||||
int pos = 1;
|
||||
while ( paramSpecItr.hasNext() ) {
|
||||
|
@ -106,11 +106,12 @@ public class BasicExecutor implements StatementExecutor {
|
|||
}
|
||||
}
|
||||
|
||||
return session.getTransactionCoordinator().getJdbcCoordinator().getResultSetReturn().executeUpdate( st );
|
||||
return session.getJdbcCoordinator().getResultSetReturn().executeUpdate( st );
|
||||
}
|
||||
finally {
|
||||
if ( st != null ) {
|
||||
session.getTransactionCoordinator().getJdbcCoordinator().release( st );
|
||||
session.getJdbcCoordinator().getResourceRegistry().release( st );
|
||||
session.getJdbcCoordinator().afterStatementExecution();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -130,17 +130,18 @@ public class TableBasedDeleteHandlerImpl
|
|||
int resultCount = 0;
|
||||
try {
|
||||
try {
|
||||
ps = session.getTransactionCoordinator().getJdbcCoordinator().getStatementPreparer().prepareStatement( idInsertSelect, false );
|
||||
ps = session.getJdbcCoordinator().getStatementPreparer().prepareStatement( idInsertSelect, false );
|
||||
int pos = 1;
|
||||
pos += handlePrependedParametersOnIdSelection( ps, session, pos );
|
||||
for ( ParameterSpecification parameterSpecification : idSelectParameterSpecifications ) {
|
||||
pos += parameterSpecification.bind( ps, queryParameters, session, pos );
|
||||
}
|
||||
resultCount = session.getTransactionCoordinator().getJdbcCoordinator().getResultSetReturn().executeUpdate( ps );
|
||||
resultCount = session.getJdbcCoordinator().getResultSetReturn().executeUpdate( ps );
|
||||
}
|
||||
finally {
|
||||
if ( ps != null ) {
|
||||
session.getTransactionCoordinator().getJdbcCoordinator().release( ps );
|
||||
session.getJdbcCoordinator().getResourceRegistry().release( ps );
|
||||
session.getJdbcCoordinator().afterStatementExecution();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -152,16 +153,17 @@ public class TableBasedDeleteHandlerImpl
|
|||
for ( String delete : deletes ) {
|
||||
try {
|
||||
try {
|
||||
ps = session.getTransactionCoordinator()
|
||||
ps = session
|
||||
.getJdbcCoordinator()
|
||||
.getStatementPreparer()
|
||||
.prepareStatement( delete, false );
|
||||
handleAddedParametersOnDelete( ps, session );
|
||||
session.getTransactionCoordinator().getJdbcCoordinator().getResultSetReturn().executeUpdate( ps );
|
||||
session.getJdbcCoordinator().getResultSetReturn().executeUpdate( ps );
|
||||
}
|
||||
finally {
|
||||
if ( ps != null ) {
|
||||
session.getTransactionCoordinator().getJdbcCoordinator().release( ps );
|
||||
session.getJdbcCoordinator().getResourceRegistry().release( ps );
|
||||
session.getJdbcCoordinator().afterStatementExecution();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -130,17 +130,18 @@ public class TableBasedUpdateHandlerImpl
|
|||
int resultCount = 0;
|
||||
try {
|
||||
try {
|
||||
ps = session.getTransactionCoordinator().getJdbcCoordinator().getStatementPreparer().prepareStatement( idInsertSelect, false );
|
||||
ps = session.getJdbcCoordinator().getStatementPreparer().prepareStatement( idInsertSelect, false );
|
||||
int sum = 1;
|
||||
sum += handlePrependedParametersOnIdSelection( ps, session, sum );
|
||||
for ( ParameterSpecification parameterSpecification : idSelectParameterSpecifications ) {
|
||||
sum += parameterSpecification.bind( ps, queryParameters, session, sum );
|
||||
}
|
||||
resultCount = session.getTransactionCoordinator().getJdbcCoordinator().getResultSetReturn().executeUpdate( ps );
|
||||
resultCount = session.getJdbcCoordinator().getResultSetReturn().executeUpdate( ps );
|
||||
}
|
||||
finally {
|
||||
if ( ps != null ) {
|
||||
session.getTransactionCoordinator().getJdbcCoordinator().release( ps );
|
||||
session.getJdbcCoordinator().getResourceRegistry().release( ps );
|
||||
session.getJdbcCoordinator().afterStatementExecution();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -155,7 +156,7 @@ public class TableBasedUpdateHandlerImpl
|
|||
}
|
||||
try {
|
||||
try {
|
||||
ps = session.getTransactionCoordinator().getJdbcCoordinator().getStatementPreparer().prepareStatement( updates[i], false );
|
||||
ps = session.getJdbcCoordinator().getStatementPreparer().prepareStatement( updates[i], false );
|
||||
if ( assignmentParameterSpecifications[i] != null ) {
|
||||
int position = 1; // jdbc params are 1-based
|
||||
for ( int x = 0; x < assignmentParameterSpecifications[i].length; x++ ) {
|
||||
|
@ -163,11 +164,12 @@ public class TableBasedUpdateHandlerImpl
|
|||
}
|
||||
handleAddedParametersOnUpdate( ps, session, position );
|
||||
}
|
||||
session.getTransactionCoordinator().getJdbcCoordinator().getResultSetReturn().executeUpdate( ps );
|
||||
session.getJdbcCoordinator().getResultSetReturn().executeUpdate( ps );
|
||||
}
|
||||
finally {
|
||||
if ( ps != null ) {
|
||||
session.getTransactionCoordinator().getJdbcCoordinator().release( ps );
|
||||
session.getJdbcCoordinator().getResourceRegistry().release( ps );
|
||||
session.getJdbcCoordinator().afterStatementExecution();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -61,20 +61,16 @@ public class Helper {
|
|||
TemporaryTableCreationWork work = new TemporaryTableCreationWork( idTableInfo, session.getFactory() );
|
||||
|
||||
if ( ddlTransactionHandling == TempTableDdlTransactionHandling.NONE ) {
|
||||
final Connection connection = session.getTransactionCoordinator()
|
||||
.getJdbcCoordinator()
|
||||
final Connection connection = session.getJdbcCoordinator()
|
||||
.getLogicalConnection()
|
||||
.getConnection();
|
||||
.getPhysicalConnection();
|
||||
|
||||
work.execute( connection );
|
||||
|
||||
session.getTransactionCoordinator()
|
||||
.getJdbcCoordinator()
|
||||
.afterStatementExecution();
|
||||
session.getJdbcCoordinator().afterStatementExecution();
|
||||
}
|
||||
else {
|
||||
session.getTransactionCoordinator()
|
||||
.getTransaction()
|
||||
.createIsolationDelegate()
|
||||
.delegateWork( work, ddlTransactionHandling == TempTableDdlTransactionHandling.ISOLATE_AND_TRANSACT );
|
||||
}
|
||||
|
@ -143,20 +139,16 @@ public class Helper {
|
|||
if ( afterUseAction == AfterUseAction.DROP ) {
|
||||
TemporaryTableDropWork work = new TemporaryTableDropWork( idTableInfo, session.getFactory() );
|
||||
if ( ddlTransactionHandling == TempTableDdlTransactionHandling.NONE ) {
|
||||
final Connection connection = session.getTransactionCoordinator()
|
||||
.getJdbcCoordinator()
|
||||
final Connection connection = session.getJdbcCoordinator()
|
||||
.getLogicalConnection()
|
||||
.getConnection();
|
||||
.getPhysicalConnection();
|
||||
|
||||
work.execute( connection );
|
||||
|
||||
session.getTransactionCoordinator()
|
||||
.getJdbcCoordinator()
|
||||
.afterStatementExecution();
|
||||
session.getJdbcCoordinator().afterStatementExecution();
|
||||
}
|
||||
else {
|
||||
session.getTransactionCoordinator()
|
||||
.getTransaction()
|
||||
.createIsolationDelegate()
|
||||
.delegateWork( work, ddlTransactionHandling == TempTableDdlTransactionHandling.ISOLATE_AND_TRANSACT );
|
||||
}
|
||||
|
@ -166,8 +158,8 @@ public class Helper {
|
|||
PreparedStatement ps = null;
|
||||
try {
|
||||
final String sql = "delete from " + idTableInfo.getQualifiedIdTableName();
|
||||
ps = session.getTransactionCoordinator().getJdbcCoordinator().getStatementPreparer().prepareStatement( sql, false );
|
||||
session.getTransactionCoordinator().getJdbcCoordinator().getResultSetReturn().executeUpdate( ps );
|
||||
ps = session.getJdbcCoordinator().getStatementPreparer().prepareStatement( sql, false );
|
||||
session.getJdbcCoordinator().getResultSetReturn().executeUpdate( ps );
|
||||
}
|
||||
catch( Throwable t ) {
|
||||
log.unableToCleanupTemporaryIdTable(t);
|
||||
|
@ -175,7 +167,7 @@ public class Helper {
|
|||
finally {
|
||||
if ( ps != null ) {
|
||||
try {
|
||||
session.getTransactionCoordinator().getJdbcCoordinator().release( ps );
|
||||
session.getJdbcCoordinator().getResourceRegistry().release( ps );
|
||||
}
|
||||
catch( Throwable ignore ) {
|
||||
// ignore
|
||||
|
|
|
@ -53,9 +53,9 @@ public class GUIDGenerator implements IdentifierGenerator {
|
|||
public Serializable generate(SessionImplementor session, Object obj) throws HibernateException {
|
||||
final String sql = session.getFactory().getDialect().getSelectGUIDString();
|
||||
try {
|
||||
PreparedStatement st = session.getTransactionCoordinator().getJdbcCoordinator().getStatementPreparer().prepareStatement( sql );
|
||||
PreparedStatement st = session.getJdbcCoordinator().getStatementPreparer().prepareStatement( sql );
|
||||
try {
|
||||
ResultSet rs = session.getTransactionCoordinator().getJdbcCoordinator().getResultSetReturn().extract( st );
|
||||
ResultSet rs = session.getJdbcCoordinator().getResultSetReturn().extract( st );
|
||||
final String result;
|
||||
try {
|
||||
if ( !rs.next() ) {
|
||||
|
@ -64,13 +64,14 @@ public class GUIDGenerator implements IdentifierGenerator {
|
|||
result = rs.getString(1);
|
||||
}
|
||||
finally {
|
||||
session.getTransactionCoordinator().getJdbcCoordinator().release( rs, st );
|
||||
session.getJdbcCoordinator().getResourceRegistry().release( rs, st );
|
||||
}
|
||||
LOG.guidGenerated(result);
|
||||
return result;
|
||||
}
|
||||
finally {
|
||||
session.getTransactionCoordinator().getJdbcCoordinator().release( st );
|
||||
session.getJdbcCoordinator().getResourceRegistry().release( st );
|
||||
session.getJdbcCoordinator().afterStatementExecution();
|
||||
}
|
||||
}
|
||||
catch (SQLException sqle) {
|
||||
|
|
|
@ -86,14 +86,14 @@ public class IdentityGenerator extends AbstractPostInsertGenerator {
|
|||
}
|
||||
|
||||
protected PreparedStatement prepare(String insertSQL, SessionImplementor session) throws SQLException {
|
||||
return session.getTransactionCoordinator()
|
||||
return session
|
||||
.getJdbcCoordinator()
|
||||
.getStatementPreparer()
|
||||
.prepareStatement( insertSQL, PreparedStatement.RETURN_GENERATED_KEYS );
|
||||
}
|
||||
|
||||
public Serializable executeAndExtract(PreparedStatement insert, SessionImplementor session) throws SQLException {
|
||||
session.getTransactionCoordinator().getJdbcCoordinator().getResultSetReturn().executeUpdate( insert );
|
||||
session.getJdbcCoordinator().getResultSetReturn().executeUpdate( insert );
|
||||
ResultSet rs = null;
|
||||
try {
|
||||
rs = insert.getGeneratedKeys();
|
||||
|
@ -105,7 +105,7 @@ public class IdentityGenerator extends AbstractPostInsertGenerator {
|
|||
}
|
||||
finally {
|
||||
if ( rs != null ) {
|
||||
session.getTransactionCoordinator().getJdbcCoordinator().release( rs, insert );
|
||||
session.getJdbcCoordinator().getResourceRegistry().release( rs, insert );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -134,14 +134,14 @@ public class IdentityGenerator extends AbstractPostInsertGenerator {
|
|||
}
|
||||
|
||||
protected PreparedStatement prepare(String insertSQL, SessionImplementor session) throws SQLException {
|
||||
return session.getTransactionCoordinator()
|
||||
return session
|
||||
.getJdbcCoordinator()
|
||||
.getStatementPreparer()
|
||||
.prepareStatement( insertSQL, PreparedStatement.NO_GENERATED_KEYS );
|
||||
}
|
||||
|
||||
public Serializable executeAndExtract(PreparedStatement insert, SessionImplementor session) throws SQLException {
|
||||
ResultSet rs = session.getTransactionCoordinator().getJdbcCoordinator().getResultSetReturn().execute( insert );
|
||||
ResultSet rs = session.getJdbcCoordinator().getResultSetReturn().execute( insert );
|
||||
try {
|
||||
return IdentifierGeneratorHelper.getGeneratedIdentity(
|
||||
rs,
|
||||
|
@ -150,7 +150,7 @@ public class IdentityGenerator extends AbstractPostInsertGenerator {
|
|||
);
|
||||
}
|
||||
finally {
|
||||
session.getTransactionCoordinator().getJdbcCoordinator().release( rs, insert );
|
||||
session.getJdbcCoordinator().getResourceRegistry().release( rs, insert );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -124,9 +124,9 @@ public class IncrementGenerator implements IdentifierGenerator, Configurable {
|
|||
LOG.debugf( "Fetching initial value: %s", sql );
|
||||
}
|
||||
try {
|
||||
PreparedStatement st = session.getTransactionCoordinator().getJdbcCoordinator().getStatementPreparer().prepareStatement( sql );
|
||||
PreparedStatement st = session.getJdbcCoordinator().getStatementPreparer().prepareStatement( sql );
|
||||
try {
|
||||
ResultSet rs = session.getTransactionCoordinator().getJdbcCoordinator().getResultSetReturn().extract( st );
|
||||
ResultSet rs = session.getJdbcCoordinator().getResultSetReturn().extract( st );
|
||||
try {
|
||||
if (rs.next()) previousValueHolder.initialize(rs, 0L).increment();
|
||||
else previousValueHolder.initialize(1L);
|
||||
|
@ -136,11 +136,12 @@ public class IncrementGenerator implements IdentifierGenerator, Configurable {
|
|||
}
|
||||
}
|
||||
finally {
|
||||
session.getTransactionCoordinator().getJdbcCoordinator().release( rs, st );
|
||||
session.getJdbcCoordinator().getResourceRegistry().release( rs, st );
|
||||
}
|
||||
}
|
||||
finally {
|
||||
session.getTransactionCoordinator().getJdbcCoordinator().release( st );
|
||||
session.getJdbcCoordinator().getResourceRegistry().release( st );
|
||||
session.getJdbcCoordinator().afterStatementExecution();
|
||||
}
|
||||
}
|
||||
catch (SQLException sqle) {
|
||||
|
|
|
@ -192,7 +192,7 @@ public class MultipleHiLoPerTableGenerator implements PersistentIdentifierGenera
|
|||
//keep the behavior consistent even for boundary usages
|
||||
IntegralDataTypeHolder value = null;
|
||||
while ( value == null || value.lt( 1 ) ) {
|
||||
value = session.getTransactionCoordinator().getTransaction().createIsolationDelegate().delegateWork( work, true );
|
||||
value = session.getTransactionCoordinator().createIsolationDelegate().delegateWork( work, true );
|
||||
}
|
||||
return value.makeValue();
|
||||
}
|
||||
|
@ -200,7 +200,7 @@ public class MultipleHiLoPerTableGenerator implements PersistentIdentifierGenera
|
|||
return hiloOptimizer.generate(
|
||||
new AccessCallback() {
|
||||
public IntegralDataTypeHolder getNextValue() {
|
||||
return session.getTransactionCoordinator().getTransaction().createIsolationDelegate().delegateWork(
|
||||
return session.getTransactionCoordinator().createIsolationDelegate().delegateWork(
|
||||
work,
|
||||
true
|
||||
);
|
||||
|
|
|
@ -119,9 +119,9 @@ public class SequenceGenerator
|
|||
|
||||
protected IntegralDataTypeHolder generateHolder(SessionImplementor session) {
|
||||
try {
|
||||
PreparedStatement st = session.getTransactionCoordinator().getJdbcCoordinator().getStatementPreparer().prepareStatement( sql );
|
||||
PreparedStatement st = session.getJdbcCoordinator().getStatementPreparer().prepareStatement( sql );
|
||||
try {
|
||||
ResultSet rs = session.getTransactionCoordinator().getJdbcCoordinator().getResultSetReturn().extract( st );
|
||||
ResultSet rs = session.getJdbcCoordinator().getResultSetReturn().extract( st );
|
||||
try {
|
||||
rs.next();
|
||||
IntegralDataTypeHolder result = buildHolder();
|
||||
|
@ -130,11 +130,12 @@ public class SequenceGenerator
|
|||
return result;
|
||||
}
|
||||
finally {
|
||||
session.getTransactionCoordinator().getJdbcCoordinator().release( rs, st );
|
||||
session.getJdbcCoordinator().getResourceRegistry().release( rs, st );
|
||||
}
|
||||
}
|
||||
finally {
|
||||
session.getTransactionCoordinator().getJdbcCoordinator().release( st );
|
||||
session.getJdbcCoordinator().getResourceRegistry().release( st );
|
||||
session.getJdbcCoordinator().afterStatementExecution();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -108,12 +108,12 @@ public class SequenceIdentityGenerator
|
|||
|
||||
@Override
|
||||
protected PreparedStatement prepare(String insertSQL, SessionImplementor session) throws SQLException {
|
||||
return session.getTransactionCoordinator().getJdbcCoordinator().getStatementPreparer().prepareStatement( insertSQL, keyColumns );
|
||||
return session.getJdbcCoordinator().getStatementPreparer().prepareStatement( insertSQL, keyColumns );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Serializable executeAndExtract(PreparedStatement insert, SessionImplementor session) throws SQLException {
|
||||
session.getTransactionCoordinator().getJdbcCoordinator().getResultSetReturn().executeUpdate( insert );
|
||||
session.getJdbcCoordinator().getResultSetReturn().executeUpdate( insert );
|
||||
return IdentifierGeneratorHelper.getGeneratedIdentity(
|
||||
insert.getGeneratedKeys(),
|
||||
getPersister().getRootTableKeyColumnNames()[0],
|
||||
|
|
|
@ -105,9 +105,9 @@ public class SequenceStructure implements DatabaseStructure {
|
|||
public IntegralDataTypeHolder getNextValue() {
|
||||
accessCounter++;
|
||||
try {
|
||||
final PreparedStatement st = session.getTransactionCoordinator().getJdbcCoordinator().getStatementPreparer().prepareStatement( sql );
|
||||
final PreparedStatement st = session.getJdbcCoordinator().getStatementPreparer().prepareStatement( sql );
|
||||
try {
|
||||
final ResultSet rs = session.getTransactionCoordinator().getJdbcCoordinator().getResultSetReturn().extract( st );
|
||||
final ResultSet rs = session.getJdbcCoordinator().getResultSetReturn().extract( st );
|
||||
try {
|
||||
rs.next();
|
||||
final IntegralDataTypeHolder value = IdentifierGeneratorHelper.getIntegralDataTypeHolder( numberType );
|
||||
|
@ -119,7 +119,7 @@ public class SequenceStructure implements DatabaseStructure {
|
|||
}
|
||||
finally {
|
||||
try {
|
||||
session.getTransactionCoordinator().getJdbcCoordinator().release( rs, st );
|
||||
session.getJdbcCoordinator().getResourceRegistry().release( rs, st );
|
||||
}
|
||||
catch( Throwable ignore ) {
|
||||
// intentionally empty
|
||||
|
@ -127,7 +127,8 @@ public class SequenceStructure implements DatabaseStructure {
|
|||
}
|
||||
}
|
||||
finally {
|
||||
session.getTransactionCoordinator().getJdbcCoordinator().release( st );
|
||||
session.getJdbcCoordinator().getResourceRegistry().release( st );
|
||||
session.getJdbcCoordinator().afterStatementExecution();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -543,7 +543,7 @@ public class TableGenerator implements PersistentIdentifierGenerator, Configurab
|
|||
new AccessCallback() {
|
||||
@Override
|
||||
public IntegralDataTypeHolder getNextValue() {
|
||||
return session.getTransactionCoordinator().getTransaction().createIsolationDelegate().delegateWork(
|
||||
return session.getTransactionCoordinator().createIsolationDelegate().delegateWork(
|
||||
new AbstractReturningWork<IntegralDataTypeHolder>() {
|
||||
@Override
|
||||
public IntegralDataTypeHolder execute(Connection connection) throws SQLException {
|
||||
|
|
|
@ -148,7 +148,7 @@ public class TableStructure implements DatabaseStructure {
|
|||
return new AccessCallback() {
|
||||
@Override
|
||||
public IntegralDataTypeHolder getNextValue() {
|
||||
return session.getTransactionCoordinator().getTransaction().createIsolationDelegate().delegateWork(
|
||||
return session.getTransactionCoordinator().createIsolationDelegate().delegateWork(
|
||||
new AbstractReturningWork<IntegralDataTypeHolder>() {
|
||||
@Override
|
||||
public IntegralDataTypeHolder execute(Connection connection) throws SQLException {
|
||||
|
|
|
@ -79,6 +79,7 @@ public abstract class AbstractReturningDelegate implements InsertGeneratedIdenti
|
|||
protected abstract Serializable executeAndExtract(PreparedStatement insert, SessionImplementor session) throws SQLException;
|
||||
|
||||
protected void releaseStatement(PreparedStatement insert, SessionImplementor session) throws SQLException {
|
||||
session.getTransactionCoordinator().getJdbcCoordinator().release( insert );
|
||||
session.getJdbcCoordinator().getResourceRegistry().release( insert );
|
||||
session.getJdbcCoordinator().afterStatementExecution();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -52,16 +52,17 @@ public abstract class AbstractSelectingDelegate implements InsertGeneratedIdenti
|
|||
Binder binder) {
|
||||
try {
|
||||
// prepare and execute the insert
|
||||
PreparedStatement insert = session.getTransactionCoordinator()
|
||||
PreparedStatement insert = session
|
||||
.getJdbcCoordinator()
|
||||
.getStatementPreparer()
|
||||
.prepareStatement( insertSQL, PreparedStatement.NO_GENERATED_KEYS );
|
||||
try {
|
||||
binder.bindValues( insert );
|
||||
session.getTransactionCoordinator().getJdbcCoordinator().getResultSetReturn().executeUpdate( insert );
|
||||
session.getJdbcCoordinator().getResultSetReturn().executeUpdate( insert );
|
||||
}
|
||||
finally {
|
||||
session.getTransactionCoordinator().getJdbcCoordinator().release( insert );
|
||||
session.getJdbcCoordinator().getResourceRegistry().release( insert );
|
||||
session.getJdbcCoordinator().afterStatementExecution();
|
||||
}
|
||||
}
|
||||
catch ( SQLException sqle ) {
|
||||
|
@ -76,22 +77,23 @@ public abstract class AbstractSelectingDelegate implements InsertGeneratedIdenti
|
|||
|
||||
try {
|
||||
//fetch the generated id in a separate query
|
||||
PreparedStatement idSelect = session.getTransactionCoordinator()
|
||||
PreparedStatement idSelect = session
|
||||
.getJdbcCoordinator()
|
||||
.getStatementPreparer()
|
||||
.prepareStatement( selectSQL, false );
|
||||
try {
|
||||
bindParameters( session, idSelect, binder.getEntity() );
|
||||
ResultSet rs = session.getTransactionCoordinator().getJdbcCoordinator().getResultSetReturn().extract( idSelect );
|
||||
ResultSet rs = session.getJdbcCoordinator().getResultSetReturn().extract( idSelect );
|
||||
try {
|
||||
return getResult( session, rs, binder.getEntity() );
|
||||
}
|
||||
finally {
|
||||
session.getTransactionCoordinator().getJdbcCoordinator().release( rs, idSelect );
|
||||
session.getJdbcCoordinator().getResourceRegistry().release( rs, idSelect );
|
||||
}
|
||||
}
|
||||
finally {
|
||||
session.getTransactionCoordinator().getJdbcCoordinator().release( idSelect );
|
||||
session.getJdbcCoordinator().getResourceRegistry().release( idSelect );
|
||||
session.getJdbcCoordinator().afterStatementExecution();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -118,7 +118,8 @@ public abstract class AbstractScrollableResults implements ScrollableResults {
|
|||
public final void close() {
|
||||
// not absolutely necessary, but does help with aggressive release
|
||||
//session.getJDBCContext().getConnectionManager().closeQueryStatement( ps, resultSet );
|
||||
session.getTransactionCoordinator().getJdbcCoordinator().release( ps );
|
||||
session.getJdbcCoordinator().getResourceRegistry().release( ps );
|
||||
session.getJdbcCoordinator().afterStatementExecution();
|
||||
try {
|
||||
session.getPersistenceContext().getLoadContexts().cleanup( resultSet );
|
||||
}
|
||||
|
|
|
@ -26,9 +26,11 @@ package org.hibernate.internal;
|
|||
import java.io.Serializable;
|
||||
import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.hibernate.ConnectionReleaseMode;
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.MappingException;
|
||||
import org.hibernate.MultiTenancyStrategy;
|
||||
|
@ -38,11 +40,14 @@ import org.hibernate.ScrollableResults;
|
|||
import org.hibernate.SessionEventListener;
|
||||
import org.hibernate.SessionException;
|
||||
import org.hibernate.SharedSessionContract;
|
||||
import org.hibernate.Transaction;
|
||||
import org.hibernate.cache.spi.CacheKey;
|
||||
import org.hibernate.cfg.Settings;
|
||||
import org.hibernate.engine.jdbc.LobCreationContext;
|
||||
import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider;
|
||||
import org.hibernate.engine.jdbc.connections.spi.JdbcConnectionAccess;
|
||||
import org.hibernate.engine.jdbc.connections.spi.MultiTenantConnectionProvider;
|
||||
import org.hibernate.engine.jdbc.spi.ConnectionObserver;
|
||||
import org.hibernate.engine.query.spi.HQLQueryPlan;
|
||||
import org.hibernate.engine.query.spi.NativeSQLQueryPlan;
|
||||
import org.hibernate.engine.query.spi.ParameterMetadata;
|
||||
|
@ -53,8 +58,7 @@ import org.hibernate.engine.spi.NamedSQLQueryDefinition;
|
|||
import org.hibernate.engine.spi.QueryParameters;
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.engine.spi.SessionImplementor;
|
||||
import org.hibernate.engine.transaction.spi.TransactionContext;
|
||||
import org.hibernate.engine.transaction.spi.TransactionEnvironment;
|
||||
import org.hibernate.engine.transaction.internal.TransactionImpl;
|
||||
import org.hibernate.id.uuid.StandardRandomStrategy;
|
||||
import org.hibernate.jdbc.WorkExecutor;
|
||||
import org.hibernate.jdbc.WorkExecutorVisitable;
|
||||
|
@ -62,6 +66,14 @@ import org.hibernate.persister.entity.EntityPersister;
|
|||
import org.hibernate.procedure.ProcedureCall;
|
||||
import org.hibernate.procedure.ProcedureCallMemento;
|
||||
import org.hibernate.procedure.internal.ProcedureCallImpl;
|
||||
import org.hibernate.resource.jdbc.spi.JdbcObserver;
|
||||
import org.hibernate.resource.jdbc.spi.JdbcSessionContext;
|
||||
import org.hibernate.resource.jdbc.spi.JdbcSessionOwner;
|
||||
import org.hibernate.resource.jdbc.spi.StatementInspector;
|
||||
import org.hibernate.resource.transaction.TransactionCoordinatorBuilder;
|
||||
import org.hibernate.resource.transaction.TransactionCoordinatorJtaBuilder;
|
||||
import org.hibernate.resource.transaction.spi.TransactionStatus;
|
||||
import org.hibernate.service.ServiceRegistry;
|
||||
import org.hibernate.type.Type;
|
||||
|
||||
/**
|
||||
|
@ -70,11 +82,13 @@ import org.hibernate.type.Type;
|
|||
* @author Gavin King
|
||||
*/
|
||||
public abstract class AbstractSessionImpl
|
||||
implements Serializable, SharedSessionContract, SessionImplementor, TransactionContext {
|
||||
implements Serializable, SharedSessionContract, SessionImplementor, JdbcSessionOwner {
|
||||
protected transient SessionFactoryImpl factory;
|
||||
private final String tenantIdentifier;
|
||||
private boolean closed;
|
||||
|
||||
protected transient Transaction currentHibernateTransaction;
|
||||
|
||||
protected AbstractSessionImpl(SessionFactoryImpl factory, String tenantIdentifier) {
|
||||
this.factory = factory;
|
||||
this.tenantIdentifier = tenantIdentifier;
|
||||
|
@ -94,14 +108,11 @@ public abstract class AbstractSessionImpl
|
|||
return factory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TransactionEnvironment getTransactionEnvironment() {
|
||||
return factory.getTransactionEnvironment();
|
||||
}
|
||||
public abstract boolean shouldAutoJoinTransaction();
|
||||
|
||||
@Override
|
||||
public <T> T execute(final LobCreationContext.Callback<T> callback) {
|
||||
return getTransactionCoordinator().getJdbcCoordinator().coordinateWork(
|
||||
return getJdbcCoordinator().coordinateWork(
|
||||
new WorkExecutorVisitable<T>() {
|
||||
@Override
|
||||
public T accept(WorkExecutor<T> workExecutor, Connection connection) throws SQLException {
|
||||
|
@ -153,7 +164,9 @@ public abstract class AbstractSessionImpl
|
|||
|
||||
@Override
|
||||
public SQLQuery createSQLQuery(NamedSQLQueryDefinition namedQueryDefinition) {
|
||||
final ParameterMetadata parameterMetadata = factory.getQueryPlanCache().getSQLParameterMetadata( namedQueryDefinition.getQueryString() );
|
||||
final ParameterMetadata parameterMetadata = factory.getQueryPlanCache().getSQLParameterMetadata(
|
||||
namedQueryDefinition.getQueryString()
|
||||
);
|
||||
final SQLQuery query = new SQLQueryImpl(
|
||||
namedQueryDefinition,
|
||||
this,
|
||||
|
@ -305,6 +318,16 @@ public abstract class AbstractSessionImpl
|
|||
return factory.getQueryPlanCache().getNativeSQLQueryPlan( spec );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Transaction getTransaction() throws HibernateException {
|
||||
errorIfClosed();
|
||||
if ( this.currentHibernateTransaction == null || this.currentHibernateTransaction.getStatus() != TransactionStatus.ACTIVE ) {
|
||||
this.currentHibernateTransaction = new TransactionImpl( getTransactionCoordinator() );
|
||||
}
|
||||
getTransactionCoordinator().pulse();
|
||||
return currentHibernateTransaction;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List list(NativeSQLQuerySpecification spec, QueryParameters queryParameters)
|
||||
throws HibernateException {
|
||||
|
@ -447,4 +470,153 @@ public abstract class AbstractSessionImpl
|
|||
return connectionProvider.supportsAggressiveRelease();
|
||||
}
|
||||
}
|
||||
|
||||
public class JdbcSessionContextImpl implements JdbcSessionContext {
|
||||
private final SessionFactoryImpl sessionFactory;
|
||||
private final StatementInspector inspector;
|
||||
private final transient ServiceRegistry serviceRegistry;
|
||||
private final transient JdbcObserver jdbcObserver;
|
||||
|
||||
public JdbcSessionContextImpl(SessionFactoryImpl sessionFactory, StatementInspector inspector) {
|
||||
this.sessionFactory = sessionFactory;
|
||||
this.inspector = inspector;
|
||||
this.serviceRegistry = sessionFactory.getServiceRegistry();
|
||||
this.jdbcObserver = new JdbcObserverImpl();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isScrollableResultSetsEnabled() {
|
||||
return settings().isScrollableResultSetsEnabled();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isGetGeneratedKeysEnabled() {
|
||||
return settings().isGetGeneratedKeysEnabled();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getFetchSize() {
|
||||
return settings().getJdbcFetchSize();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConnectionReleaseMode getConnectionReleaseMode() {
|
||||
return settings().getConnectionReleaseMode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConnectionAcquisitionMode getConnectionAcquisitionMode() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public StatementInspector getStatementInspector() {
|
||||
return inspector;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JdbcObserver getObserver() {
|
||||
return this.jdbcObserver;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SessionFactoryImplementor getSessionFactory() {
|
||||
return this.sessionFactory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ServiceRegistry getServiceRegistry() {
|
||||
return this.serviceRegistry;
|
||||
}
|
||||
|
||||
private final Settings settings() {
|
||||
return this.sessionFactory.getSettings();
|
||||
}
|
||||
}
|
||||
|
||||
public class JdbcObserverImpl implements JdbcObserver {
|
||||
|
||||
private final transient List<ConnectionObserver> observers;
|
||||
|
||||
public JdbcObserverImpl() {
|
||||
this.observers = new ArrayList<ConnectionObserver>();
|
||||
this.observers.add( new ConnectionObserverStatsBridge( factory ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void jdbcConnectionAcquisitionStart() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void jdbcConnectionAcquisitionEnd(Connection connection) {
|
||||
for ( ConnectionObserver observer : observers ) {
|
||||
observer.physicalConnectionObtained( connection );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void jdbcConnectionReleaseStart() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void jdbcConnectionReleaseEnd() {
|
||||
for ( ConnectionObserver observer : observers ) {
|
||||
observer.physicalConnectionReleased();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void jdbcPrepareStatementStart() {
|
||||
getEventListenerManager().jdbcPrepareStatementStart();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void jdbcPrepareStatementEnd() {
|
||||
for ( ConnectionObserver observer : observers ) {
|
||||
observer.statementPrepared();
|
||||
}
|
||||
getEventListenerManager().jdbcPrepareStatementEnd();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void jdbcExecuteStatementStart() {
|
||||
getEventListenerManager().jdbcExecuteStatementStart();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void jdbcExecuteStatementEnd() {
|
||||
getEventListenerManager().jdbcExecuteStatementEnd();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void jdbcExecuteBatchStart() {
|
||||
getEventListenerManager().jdbcExecuteBatchStart();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void jdbcExecuteBatchEnd() {
|
||||
getEventListenerManager().jdbcExecuteBatchEnd();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public TransactionCoordinatorBuilder getTransactionCoordinatorBuilder() {
|
||||
TransactionCoordinatorBuilder transactionCoordinatorBuilder = factory.getServiceRegistry()
|
||||
.getService( TransactionCoordinatorBuilder.class );
|
||||
|
||||
if ( transactionCoordinatorBuilder instanceof TransactionCoordinatorJtaBuilder ) {
|
||||
((TransactionCoordinatorJtaBuilder) transactionCoordinatorBuilder).setJtaPlatform(
|
||||
factory.getSettings()
|
||||
.getJtaPlatform()
|
||||
).setAutoJoinTransactions( shouldAutoJoinTransaction() ).setPerformJtaThreadTracking(
|
||||
factory.getSettings()
|
||||
.isJtaTrackByThread()
|
||||
).setPreferUserTransactions( factory.getSettings().isPreferUserTransaction() );
|
||||
}
|
||||
|
||||
return transactionCoordinatorBuilder;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -85,7 +85,8 @@ public final class IteratorImpl implements HibernateIterator {
|
|||
public void close() throws JDBCException {
|
||||
if (ps!=null) {
|
||||
LOG.debug("Closing iterator");
|
||||
session.getTransactionCoordinator().getJdbcCoordinator().release( ps );
|
||||
session.getJdbcCoordinator().getResourceRegistry().release( ps );
|
||||
session.getJdbcCoordinator().afterStatementExecution();
|
||||
ps = null;
|
||||
rs = null;
|
||||
hasNext = false;
|
||||
|
|
|
@ -23,6 +23,8 @@
|
|||
*/
|
||||
package org.hibernate.internal;
|
||||
|
||||
import javax.naming.Reference;
|
||||
import javax.naming.StringRefAddr;
|
||||
import java.io.IOException;
|
||||
import java.io.InvalidObjectException;
|
||||
import java.io.ObjectInputStream;
|
||||
|
@ -41,8 +43,8 @@ import java.util.Properties;
|
|||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import javax.naming.Reference;
|
||||
import javax.naming.StringRefAddr;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
import org.hibernate.AssertionFailure;
|
||||
import org.hibernate.Cache;
|
||||
|
@ -61,6 +63,7 @@ import org.hibernate.SessionFactory;
|
|||
import org.hibernate.SessionFactoryObserver;
|
||||
import org.hibernate.StatelessSession;
|
||||
import org.hibernate.StatelessSessionBuilder;
|
||||
import org.hibernate.Transaction;
|
||||
import org.hibernate.TypeHelper;
|
||||
import org.hibernate.boot.cfgxml.spi.CfgXmlAccessService;
|
||||
import org.hibernate.boot.cfgxml.spi.LoadedConfig;
|
||||
|
@ -94,6 +97,7 @@ import org.hibernate.engine.config.spi.ConfigurationService;
|
|||
import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider;
|
||||
import org.hibernate.engine.jdbc.connections.spi.JdbcConnectionAccess;
|
||||
import org.hibernate.engine.jdbc.connections.spi.MultiTenantConnectionProvider;
|
||||
import org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl;
|
||||
import org.hibernate.engine.jdbc.spi.JdbcServices;
|
||||
import org.hibernate.engine.jdbc.spi.SqlExceptionHelper;
|
||||
import org.hibernate.engine.jndi.spi.JndiService;
|
||||
|
@ -110,10 +114,7 @@ import org.hibernate.engine.spi.NamedSQLQueryDefinition;
|
|||
import org.hibernate.engine.spi.SessionBuilderImplementor;
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.engine.spi.SessionOwner;
|
||||
import org.hibernate.engine.transaction.internal.TransactionCoordinatorImpl;
|
||||
import org.hibernate.engine.transaction.jta.platform.spi.JtaPlatform;
|
||||
import org.hibernate.engine.transaction.spi.TransactionEnvironment;
|
||||
import org.hibernate.engine.transaction.spi.TransactionFactory;
|
||||
import org.hibernate.event.service.spi.EventListenerGroup;
|
||||
import org.hibernate.event.service.spi.EventListenerRegistry;
|
||||
import org.hibernate.event.spi.EventType;
|
||||
|
@ -136,6 +137,7 @@ import org.hibernate.persister.entity.Queryable;
|
|||
import org.hibernate.persister.spi.PersisterCreationContext;
|
||||
import org.hibernate.persister.spi.PersisterFactory;
|
||||
import org.hibernate.proxy.EntityNotFoundDelegate;
|
||||
import org.hibernate.resource.transaction.TransactionCoordinator;
|
||||
import org.hibernate.secure.spi.GrantedPermission;
|
||||
import org.hibernate.secure.spi.JaccPermissionDeclarations;
|
||||
import org.hibernate.secure.spi.JaccService;
|
||||
|
@ -153,8 +155,6 @@ import org.hibernate.type.AssociationType;
|
|||
import org.hibernate.type.Type;
|
||||
import org.hibernate.type.TypeResolver;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
|
||||
/**
|
||||
* Concrete implementation of the <tt>SessionFactory</tt> interface. Has the following
|
||||
|
@ -182,7 +182,10 @@ import org.jboss.logging.Logger;
|
|||
public final class SessionFactoryImpl
|
||||
implements SessionFactoryImplementor {
|
||||
|
||||
private static final CoreMessageLogger LOG = Logger.getMessageLogger(CoreMessageLogger.class, SessionFactoryImpl.class.getName());
|
||||
private static final CoreMessageLogger LOG = Logger.getMessageLogger(
|
||||
CoreMessageLogger.class,
|
||||
SessionFactoryImpl.class.getName()
|
||||
);
|
||||
private static final IdentifierGenerator UUID_GENERATOR = UUIDGenerator.buildSessionFactoryUniqueIdentifierGenerator();
|
||||
|
||||
private final String name;
|
||||
|
@ -213,7 +216,6 @@ public final class SessionFactoryImpl
|
|||
private transient boolean isClosed;
|
||||
private final transient TypeResolver typeResolver;
|
||||
private final transient TypeHelper typeHelper;
|
||||
private final transient TransactionEnvironment transactionEnvironment;
|
||||
private final transient SessionFactoryOptions sessionFactoryOptions;
|
||||
|
||||
public SessionFactoryImpl(final MetadataImplementor metadata, SessionFactoryOptions options) {
|
||||
|
@ -515,7 +517,6 @@ public final class SessionFactoryImpl
|
|||
fetchProfiles.put( fetchProfile.getName(), fetchProfile );
|
||||
}
|
||||
|
||||
this.transactionEnvironment = new TransactionEnvironmentImpl( this );
|
||||
this.observer.sessionFactoryCreated( this );
|
||||
|
||||
SessionFactoryRegistry.INSTANCE.addSessionFactory(
|
||||
|
@ -690,10 +691,6 @@ public final class SessionFactoryImpl
|
|||
this.observer.addObserver( observer );
|
||||
}
|
||||
|
||||
public TransactionEnvironment getTransactionEnvironment() {
|
||||
return transactionEnvironment;
|
||||
}
|
||||
|
||||
public Properties getProperties() {
|
||||
return properties;
|
||||
}
|
||||
|
@ -1123,10 +1120,6 @@ public final class SessionFactoryImpl
|
|||
return identifierGenerators.get(rootEntityName);
|
||||
}
|
||||
|
||||
private TransactionFactory transactionFactory() {
|
||||
return serviceRegistry.getService( TransactionFactory.class );
|
||||
}
|
||||
|
||||
private boolean canAccessTransactionManager() {
|
||||
try {
|
||||
return serviceRegistry.getService( JtaPlatform.class ).retrieveTransactionManager() != null;
|
||||
|
@ -1149,9 +1142,9 @@ public final class SessionFactoryImpl
|
|||
}
|
||||
|
||||
if ( "jta".equals( impl ) ) {
|
||||
if ( ! transactionFactory().compatibleWithJtaSynchronization() ) {
|
||||
LOG.autoFlushWillNotWork();
|
||||
}
|
||||
// if ( ! transactionFactory().compatibleWithJtaSynchronization() ) {
|
||||
// LOG.autoFlushWillNotWork();
|
||||
// }
|
||||
return new JTASessionContext( this );
|
||||
}
|
||||
else if ( "thread".equals( impl ) ) {
|
||||
|
@ -1228,7 +1221,15 @@ public final class SessionFactoryImpl
|
|||
listeners = settings.getBaselineSessionEventsListenerBuilder().buildBaselineList();
|
||||
}
|
||||
|
||||
protected TransactionCoordinatorImpl getTransactionCoordinator() {
|
||||
protected TransactionCoordinator getTransactionCoordinator() {
|
||||
return null;
|
||||
}
|
||||
|
||||
protected JdbcCoordinatorImpl getJdbcCoordinator() {
|
||||
return null;
|
||||
}
|
||||
|
||||
protected Transaction getTransaction() {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -1244,6 +1245,8 @@ public final class SessionFactoryImpl
|
|||
sessionFactory,
|
||||
sessionOwner,
|
||||
getTransactionCoordinator(),
|
||||
getJdbcCoordinator(),
|
||||
getTransaction(),
|
||||
getTransactionCompletionProcesses(),
|
||||
autoJoinTransactions,
|
||||
sessionFactory.settings.getRegionFactory().nextTimestamp(),
|
||||
|
|
|
@ -23,6 +23,8 @@
|
|||
*/
|
||||
package org.hibernate.internal;
|
||||
|
||||
import javax.persistence.EntityNotFoundException;
|
||||
import javax.transaction.SystemException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.ObjectInputStream;
|
||||
|
@ -42,7 +44,8 @@ import java.util.LinkedHashMap;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import javax.persistence.EntityNotFoundException;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
import org.hibernate.AssertionFailure;
|
||||
import org.hibernate.CacheMode;
|
||||
|
@ -85,6 +88,8 @@ import org.hibernate.engine.internal.SessionEventListenerManagerImpl;
|
|||
import org.hibernate.engine.internal.StatefulPersistenceContext;
|
||||
import org.hibernate.engine.jdbc.LobCreator;
|
||||
import org.hibernate.engine.jdbc.NonContextualLobCreator;
|
||||
import org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl;
|
||||
import org.hibernate.engine.jdbc.spi.JdbcCoordinator;
|
||||
import org.hibernate.engine.query.spi.FilterQueryPlan;
|
||||
import org.hibernate.engine.query.spi.HQLQueryPlan;
|
||||
import org.hibernate.engine.query.spi.NativeSQLQueryPlan;
|
||||
|
@ -99,9 +104,7 @@ import org.hibernate.engine.spi.QueryParameters;
|
|||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.engine.spi.SessionOwner;
|
||||
import org.hibernate.engine.spi.Status;
|
||||
import org.hibernate.engine.transaction.internal.TransactionCoordinatorImpl;
|
||||
import org.hibernate.engine.transaction.spi.TransactionCoordinator;
|
||||
import org.hibernate.engine.transaction.spi.TransactionImplementor;
|
||||
import org.hibernate.engine.transaction.internal.jta.JtaStatusHelper;
|
||||
import org.hibernate.engine.transaction.spi.TransactionObserver;
|
||||
import org.hibernate.event.service.spi.EventListenerGroup;
|
||||
import org.hibernate.event.service.spi.EventListenerRegistry;
|
||||
|
@ -154,12 +157,15 @@ import org.hibernate.pretty.MessageHelper;
|
|||
import org.hibernate.procedure.ProcedureCall;
|
||||
import org.hibernate.proxy.HibernateProxy;
|
||||
import org.hibernate.proxy.LazyInitializer;
|
||||
import org.hibernate.resource.jdbc.spi.JdbcSessionContext;
|
||||
import org.hibernate.resource.jdbc.spi.StatementInspector;
|
||||
import org.hibernate.resource.transaction.TransactionCoordinator;
|
||||
import org.hibernate.resource.transaction.backend.jta.internal.JtaTransactionCoordinatorImpl;
|
||||
import org.hibernate.resource.transaction.spi.TransactionStatus;
|
||||
import org.hibernate.stat.SessionStatistics;
|
||||
import org.hibernate.stat.internal.SessionStatisticsImpl;
|
||||
import org.hibernate.type.Type;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
/**
|
||||
* Concrete implementation of a Session.
|
||||
*
|
||||
|
@ -180,9 +186,12 @@ public final class SessionImpl extends AbstractSessionImpl implements EventSourc
|
|||
// a separate class responsible for generating/dispatching events just duplicates most of the Session methods...
|
||||
// passing around separate interceptor, factory, actionQueue, and persistentContext is not manageable...
|
||||
|
||||
private static final CoreMessageLogger LOG = Logger.getMessageLogger(CoreMessageLogger.class, SessionImpl.class.getName());
|
||||
private static final CoreMessageLogger LOG = Logger.getMessageLogger(
|
||||
CoreMessageLogger.class,
|
||||
SessionImpl.class.getName()
|
||||
);
|
||||
|
||||
private static final boolean TRACE_ENABLED = LOG.isTraceEnabled();
|
||||
private static final boolean TRACE_ENABLED = LOG.isTraceEnabled();
|
||||
|
||||
private transient long timestamp;
|
||||
|
||||
|
@ -190,7 +199,8 @@ public final class SessionImpl extends AbstractSessionImpl implements EventSourc
|
|||
|
||||
private transient ActionQueue actionQueue;
|
||||
private transient StatefulPersistenceContext persistenceContext;
|
||||
private transient TransactionCoordinatorImpl transactionCoordinator;
|
||||
private transient TransactionCoordinator transactionCoordinator;
|
||||
private transient JdbcCoordinatorImpl jdbcCoordinator;
|
||||
private transient Interceptor interceptor;
|
||||
private transient EntityNameResolver entityNameResolver = new CoordinatingEntityNameResolver();
|
||||
|
||||
|
@ -212,6 +222,8 @@ public final class SessionImpl extends AbstractSessionImpl implements EventSourc
|
|||
|
||||
private SessionEventListenerManagerImpl sessionEventsManager = new SessionEventListenerManagerImpl();
|
||||
|
||||
private transient JdbcSessionContext jdbcSessionContext;
|
||||
|
||||
/**
|
||||
* Constructor used for openSession(...) processing, as well as construction
|
||||
* of sessions for getCurrentSession().
|
||||
|
@ -232,7 +244,9 @@ public final class SessionImpl extends AbstractSessionImpl implements EventSourc
|
|||
final Connection connection,
|
||||
final SessionFactoryImpl factory,
|
||||
final SessionOwner sessionOwner,
|
||||
final TransactionCoordinatorImpl transactionCoordinator,
|
||||
final TransactionCoordinator transactionCoordinator,
|
||||
final JdbcCoordinatorImpl jdbcCoordinator,
|
||||
final Transaction transaction,
|
||||
final ActionQueue.TransactionCompletionProcesses transactionCompletionProcesses,
|
||||
final boolean autoJoinTransactions,
|
||||
final long timestamp,
|
||||
|
@ -250,22 +264,24 @@ public final class SessionImpl extends AbstractSessionImpl implements EventSourc
|
|||
|
||||
this.autoCloseSessionEnabled = autoCloseSessionEnabled;
|
||||
this.flushBeforeCompletionEnabled = flushBeforeCompletionEnabled;
|
||||
this.jdbcSessionContext = new JdbcSessionContextImpl( factory, getStatementInspector() );
|
||||
|
||||
if ( transactionCoordinator == null ) {
|
||||
this.isTransactionCoordinatorShared = false;
|
||||
this.connectionReleaseMode = connectionReleaseMode;
|
||||
this.autoJoinTransactions = autoJoinTransactions;
|
||||
|
||||
this.transactionCoordinator = new TransactionCoordinatorImpl( connection, this );
|
||||
this.transactionCoordinator.getJdbcCoordinator().getLogicalConnection().addObserver(
|
||||
new ConnectionObserverStatsBridge( factory )
|
||||
);
|
||||
this.jdbcCoordinator = new JdbcCoordinatorImpl( connection, this );
|
||||
this.transactionCoordinator = getTransactionCoordinatorBuilder().buildTransactionCoordinator( this.jdbcCoordinator );
|
||||
this.currentHibernateTransaction = getTransaction();
|
||||
}
|
||||
else {
|
||||
if ( connection != null ) {
|
||||
throw new SessionException( "Cannot simultaneously share transaction context and specify connection" );
|
||||
}
|
||||
this.transactionCoordinator = transactionCoordinator;
|
||||
this.jdbcCoordinator = jdbcCoordinator;
|
||||
this.currentHibernateTransaction = transaction;
|
||||
this.isTransactionCoordinatorShared = true;
|
||||
this.autoJoinTransactions = false;
|
||||
if ( transactionCompletionProcesses != null ) {
|
||||
|
@ -277,36 +293,39 @@ public final class SessionImpl extends AbstractSessionImpl implements EventSourc
|
|||
"with sharing JDBC connection between sessions; ignoring"
|
||||
);
|
||||
}
|
||||
if ( connectionReleaseMode != transactionCoordinator.getJdbcCoordinator().getLogicalConnection().getConnectionReleaseMode() ) {
|
||||
if ( connectionReleaseMode != this.jdbcCoordinator.getConnectionReleaseMode() ) {
|
||||
LOG.debug(
|
||||
"Session creation specified 'connectionReleaseMode', which is invalid in conjunction " +
|
||||
"Session creation specified 'getConnectionReleaseMode', which is invalid in conjunction " +
|
||||
"with sharing JDBC connection between sessions; ignoring"
|
||||
);
|
||||
}
|
||||
this.connectionReleaseMode = transactionCoordinator.getJdbcCoordinator().getLogicalConnection().getConnectionReleaseMode();
|
||||
this.connectionReleaseMode = this.jdbcCoordinator.getConnectionReleaseMode();
|
||||
|
||||
// add a transaction observer so that we can handle delegating managed actions back to THIS session
|
||||
// versus the session that created (and therefore "owns") the transaction coordinator
|
||||
transactionObserver = new TransactionObserver() {
|
||||
@Override
|
||||
public void afterBegin(TransactionImplementor transaction) {
|
||||
public void afterBegin() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeCompletion(TransactionImplementor transaction) {
|
||||
public void beforeCompletion() {
|
||||
if ( isOpen() && flushBeforeCompletionEnabled ) {
|
||||
SessionImpl.this.managedFlush();
|
||||
}
|
||||
beforeTransactionCompletion( transaction );
|
||||
actionQueue.beforeTransactionCompletion();
|
||||
try {
|
||||
interceptor.beforeTransactionCompletion( currentHibernateTransaction );
|
||||
}
|
||||
catch (Throwable t) {
|
||||
LOG.exceptionInBeforeTransactionCompletionInterceptor( t );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterCompletion(boolean successful, TransactionImplementor transaction) {
|
||||
afterTransactionCompletion( transaction, successful );
|
||||
public void afterCompletion(boolean successful) {
|
||||
afterTransactionCompletion( successful );
|
||||
if ( isOpen() && autoCloseSessionEnabled ) {
|
||||
managedClose();
|
||||
}
|
||||
transactionCoordinator.removeObserver( this );
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -315,12 +334,14 @@ public final class SessionImpl extends AbstractSessionImpl implements EventSourc
|
|||
|
||||
loadQueryInfluencers = new LoadQueryInfluencers( factory );
|
||||
|
||||
if (factory.getStatistics().isStatisticsEnabled()) {
|
||||
if ( factory.getStatistics().isStatisticsEnabled() ) {
|
||||
factory.getStatisticsImplementor().openSession();
|
||||
}
|
||||
|
||||
if ( TRACE_ENABLED )
|
||||
LOG.tracef( "Opened session at timestamp: %s", timestamp );
|
||||
if ( TRACE_ENABLED ) {
|
||||
LOG.tracef( "Opened session at timestamp: %s", timestamp );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -367,14 +388,13 @@ public final class SessionImpl extends AbstractSessionImpl implements EventSourc
|
|||
|
||||
try {
|
||||
if ( !isTransactionCoordinatorShared ) {
|
||||
return transactionCoordinator.close();
|
||||
return jdbcCoordinator.close();
|
||||
}
|
||||
else {
|
||||
if ( getActionQueue().hasBeforeTransactionActions() || getActionQueue().hasAfterTransactionActions() ) {
|
||||
LOG.warn( "On close, shared Session had before / after transaction actions that have not yet been processed" );
|
||||
}
|
||||
else {
|
||||
transactionCoordinator.removeObserver( transactionObserver );
|
||||
LOG.warn(
|
||||
"On close, shared Session had before / after transaction actions that have not yet been processed"
|
||||
);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
@ -386,8 +406,8 @@ public final class SessionImpl extends AbstractSessionImpl implements EventSourc
|
|||
}
|
||||
|
||||
@Override
|
||||
public ConnectionReleaseMode getConnectionReleaseMode() {
|
||||
return connectionReleaseMode;
|
||||
public boolean isAutoCloseSessionEnabled() {
|
||||
return autoCloseSessionEnabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -395,29 +415,17 @@ public final class SessionImpl extends AbstractSessionImpl implements EventSourc
|
|||
return autoJoinTransactions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAutoCloseSessionEnabled() {
|
||||
return autoCloseSessionEnabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOpen() {
|
||||
checkTransactionSynchStatus();
|
||||
return !isClosed();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFlushModeNever() {
|
||||
private boolean isFlushModeNever() {
|
||||
return FlushMode.isManualFlushMode( getFlushMode() );
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFlushBeforeCompletionEnabled() {
|
||||
return flushBeforeCompletionEnabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void managedFlush() {
|
||||
private void managedFlush() {
|
||||
if ( isClosed() ) {
|
||||
LOG.trace( "Skipping auto-flush due to session closed" );
|
||||
return;
|
||||
|
@ -439,8 +447,7 @@ public final class SessionImpl extends AbstractSessionImpl implements EventSourc
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void managedClose() {
|
||||
private void managedClose() {
|
||||
LOG.trace( "Automatically closing session" );
|
||||
close();
|
||||
}
|
||||
|
@ -448,27 +455,27 @@ public final class SessionImpl extends AbstractSessionImpl implements EventSourc
|
|||
@Override
|
||||
public Connection connection() throws HibernateException {
|
||||
errorIfClosed();
|
||||
return transactionCoordinator.getJdbcCoordinator().getLogicalConnection().getConnection();
|
||||
return this.jdbcCoordinator.getLogicalConnection().getPhysicalConnection();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isConnected() {
|
||||
checkTransactionSynchStatus();
|
||||
return !isClosed() && transactionCoordinator.getJdbcCoordinator().getLogicalConnection().isOpen();
|
||||
return !isClosed() && this.jdbcCoordinator.getLogicalConnection().isOpen();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isTransactionInProgress() {
|
||||
checkTransactionSynchStatus();
|
||||
return !isClosed() && transactionCoordinator.isTransactionInProgress();
|
||||
return !isClosed() && transactionCoordinator.getTransactionDriverControl()
|
||||
.getStatus() == TransactionStatus.ACTIVE && transactionCoordinator.isJoined();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Connection disconnect() throws HibernateException {
|
||||
errorIfClosed();
|
||||
LOG.debug( "Disconnecting session" );
|
||||
transactionCoordinator.getJdbcCoordinator().releaseResources();
|
||||
return transactionCoordinator.getJdbcCoordinator().getLogicalConnection().manualDisconnect();
|
||||
return this.jdbcCoordinator.getLogicalConnection().manualDisconnect();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -476,7 +483,7 @@ public final class SessionImpl extends AbstractSessionImpl implements EventSourc
|
|||
errorIfClosed();
|
||||
LOG.debug( "Reconnecting session" );
|
||||
checkTransactionSynchStatus();
|
||||
transactionCoordinator.getJdbcCoordinator().getLogicalConnection().manualReconnect( conn );
|
||||
this.jdbcCoordinator.getLogicalConnection().manualReconnect( conn );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -500,64 +507,11 @@ public final class SessionImpl extends AbstractSessionImpl implements EventSourc
|
|||
* @param success Was the operation a success
|
||||
*/
|
||||
public void afterOperation(boolean success) {
|
||||
if ( ! transactionCoordinator.isTransactionInProgress() ) {
|
||||
transactionCoordinator.afterNonTransactionalQuery( success );
|
||||
if ( ! isTransactionInProgress() ) {
|
||||
jdbcCoordinator.afterTransaction();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterTransactionBegin(TransactionImplementor hibernateTransaction) {
|
||||
errorIfClosed();
|
||||
interceptor.afterTransactionBegin( hibernateTransaction );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeTransactionCompletion(TransactionImplementor hibernateTransaction) {
|
||||
LOG.trace( "before transaction completion" );
|
||||
actionQueue.beforeTransactionCompletion();
|
||||
try {
|
||||
interceptor.beforeTransactionCompletion( hibernateTransaction );
|
||||
}
|
||||
catch (Throwable t) {
|
||||
LOG.exceptionInBeforeTransactionCompletionInterceptor( t );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterTransactionCompletion(TransactionImplementor hibernateTransaction, boolean successful) {
|
||||
LOG.trace( "after transaction completion" );
|
||||
persistenceContext.afterTransactionCompletion();
|
||||
actionQueue.afterTransactionCompletion( successful );
|
||||
|
||||
getEventListenerManager().transactionCompletion( successful );
|
||||
|
||||
try {
|
||||
interceptor.afterTransactionCompletion( hibernateTransaction );
|
||||
}
|
||||
catch (Throwable t) {
|
||||
LOG.exceptionInAfterTransactionCompletionInterceptor( t );
|
||||
}
|
||||
|
||||
if ( autoClear ) {
|
||||
internalClear();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onPrepareStatement(String sql) {
|
||||
errorIfClosed();
|
||||
if ( StringHelper.isEmpty( sql ) ) {
|
||||
throw new AssertionFailure( "SQL to prepare was null." );
|
||||
}
|
||||
|
||||
sql = interceptor.onPrepareStatement( sql );
|
||||
|
||||
if ( StringHelper.isEmpty( sql ) ) {
|
||||
throw new AssertionFailure( "Interceptor.onPrepareStatement() returned null or empty string." );
|
||||
}
|
||||
return sql;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SessionEventListenerManagerImpl getEventListenerManager() {
|
||||
return sessionEventsManager;
|
||||
|
@ -568,36 +522,6 @@ public final class SessionImpl extends AbstractSessionImpl implements EventSourc
|
|||
getEventListenerManager().addListener( listeners );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startPrepareStatement() {
|
||||
getEventListenerManager().jdbcPrepareStatementStart();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endPrepareStatement() {
|
||||
getEventListenerManager().jdbcPrepareStatementEnd();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startStatementExecution() {
|
||||
getEventListenerManager().jdbcExecuteStatementStart();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endStatementExecution() {
|
||||
getEventListenerManager().jdbcExecuteStatementEnd();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startBatchExecution() {
|
||||
getEventListenerManager().jdbcExecuteBatchStart();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endBatchExecution() {
|
||||
getEventListenerManager().jdbcExecuteBatchEnd();
|
||||
}
|
||||
|
||||
/**
|
||||
* clear all the internal collections, just
|
||||
* to help the garbage collector, does not
|
||||
|
@ -665,9 +589,11 @@ public final class SessionImpl extends AbstractSessionImpl implements EventSourc
|
|||
}
|
||||
delayedAfterCompletion();
|
||||
}
|
||||
|
||||
|
||||
private void delayedAfterCompletion() {
|
||||
transactionCoordinator.getSynchronizationCallbackCoordinator().processAnyDelayedAfterCompletion();
|
||||
if(transactionCoordinator instanceof JtaTransactionCoordinatorImpl) {
|
||||
((JtaTransactionCoordinatorImpl)transactionCoordinator).getSynchronizationCallbackCoordinator().processAnyDelayedAfterCompletion();
|
||||
}
|
||||
}
|
||||
|
||||
// saveOrUpdate() operations ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
@ -766,7 +692,7 @@ public final class SessionImpl extends AbstractSessionImpl implements EventSourc
|
|||
}
|
||||
|
||||
private void fireLock(String entityName, Object object, LockOptions options) {
|
||||
fireLock( new LockEvent( entityName, object, options, this) );
|
||||
fireLock( new LockEvent( entityName, object, options, this ) );
|
||||
}
|
||||
|
||||
private void fireLock( Object object, LockOptions options) {
|
||||
|
@ -1229,6 +1155,7 @@ public final class SessionImpl extends AbstractSessionImpl implements EventSourc
|
|||
return false;
|
||||
}
|
||||
AutoFlushEvent event = new AutoFlushEvent( querySpaces, this );
|
||||
listeners( EventType.AUTO_FLUSH );
|
||||
for ( AutoFlushEventListener listener : listeners( EventType.AUTO_FLUSH ) ) {
|
||||
listener.onAutoFlush( event );
|
||||
}
|
||||
|
@ -1329,7 +1256,7 @@ public final class SessionImpl extends AbstractSessionImpl implements EventSourc
|
|||
success = true;
|
||||
}
|
||||
finally {
|
||||
afterOperation(success);
|
||||
afterOperation( success );
|
||||
delayedAfterCompletion();
|
||||
}
|
||||
return result;
|
||||
|
@ -1352,7 +1279,7 @@ public final class SessionImpl extends AbstractSessionImpl implements EventSourc
|
|||
result = plan.performExecuteUpdate(queryParameters, this);
|
||||
success = true;
|
||||
} finally {
|
||||
afterOperation(success);
|
||||
afterOperation( success );
|
||||
delayedAfterCompletion();
|
||||
}
|
||||
return result;
|
||||
|
@ -1464,12 +1391,6 @@ public final class SessionImpl extends AbstractSessionImpl implements EventSourc
|
|||
this.cacheMode= cacheMode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Transaction getTransaction() throws HibernateException {
|
||||
errorIfClosed();
|
||||
return transactionCoordinator.getTransaction();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Transaction beginTransaction() throws HibernateException {
|
||||
errorIfClosed();
|
||||
|
@ -1995,7 +1916,7 @@ public final class SessionImpl extends AbstractSessionImpl implements EventSourc
|
|||
@Override
|
||||
public void cancelQuery() throws HibernateException {
|
||||
errorIfClosed();
|
||||
getTransactionCoordinator().getJdbcCoordinator().cancelLastQuery();
|
||||
this.jdbcCoordinator.cancelLastQuery();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -2098,7 +2019,7 @@ public final class SessionImpl extends AbstractSessionImpl implements EventSourc
|
|||
}
|
||||
|
||||
private <T> T doWork(WorkExecutorVisitable<T> work) throws HibernateException {
|
||||
return transactionCoordinator.getJdbcCoordinator().coordinateWork( work );
|
||||
return this.jdbcCoordinator.coordinateWork( work );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -2112,6 +2033,11 @@ public final class SessionImpl extends AbstractSessionImpl implements EventSourc
|
|||
return transactionCoordinator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JdbcCoordinator getJdbcCoordinator() {
|
||||
return this.jdbcCoordinator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LoadQueryInfluencers getLoadQueryInfluencers() {
|
||||
return loadQueryInfluencers;
|
||||
|
@ -2212,26 +2138,29 @@ public final class SessionImpl extends AbstractSessionImpl implements EventSourc
|
|||
* @throws IOException Indicates a general IO stream exception
|
||||
* @throws ClassNotFoundException Indicates a class resolution issue
|
||||
*/
|
||||
private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
|
||||
private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException, SQLException {
|
||||
LOG.trace( "Deserializing session" );
|
||||
|
||||
ois.defaultReadObject();
|
||||
|
||||
entityNameResolver = new CoordinatingEntityNameResolver();
|
||||
|
||||
connectionReleaseMode = ConnectionReleaseMode.parse( ( String ) ois.readObject() );
|
||||
connectionReleaseMode = ConnectionReleaseMode.parse( (String) ois.readObject() );
|
||||
autoClear = ois.readBoolean();
|
||||
autoJoinTransactions = ois.readBoolean();
|
||||
flushMode = FlushMode.valueOf( ( String ) ois.readObject() );
|
||||
cacheMode = CacheMode.valueOf( ( String ) ois.readObject() );
|
||||
flushMode = FlushMode.valueOf( (String) ois.readObject() );
|
||||
cacheMode = CacheMode.valueOf( (String) ois.readObject() );
|
||||
flushBeforeCompletionEnabled = ois.readBoolean();
|
||||
autoCloseSessionEnabled = ois.readBoolean();
|
||||
interceptor = ( Interceptor ) ois.readObject();
|
||||
interceptor = (Interceptor) ois.readObject();
|
||||
|
||||
factory = SessionFactoryImpl.deserialize( ois );
|
||||
sessionOwner = ( SessionOwner ) ois.readObject();
|
||||
this.jdbcSessionContext = new JdbcSessionContextImpl( factory, interceptor );
|
||||
sessionOwner = (SessionOwner) ois.readObject();
|
||||
|
||||
transactionCoordinator = TransactionCoordinatorImpl.deserialize( ois, this );
|
||||
jdbcCoordinator = JdbcCoordinatorImpl.deserialize( ois, this );
|
||||
|
||||
this.transactionCoordinator = getTransactionCoordinatorBuilder().buildTransactionCoordinator( jdbcCoordinator );
|
||||
|
||||
persistenceContext = StatefulPersistenceContext.deserialize( ois, this );
|
||||
actionQueue = ActionQueue.deserialize( ois, this );
|
||||
|
@ -2253,7 +2182,7 @@ public final class SessionImpl extends AbstractSessionImpl implements EventSourc
|
|||
* @throws IOException Indicates a general IO stream exception
|
||||
*/
|
||||
private void writeObject(ObjectOutputStream oos) throws IOException {
|
||||
if ( ! transactionCoordinator.getJdbcCoordinator().isReadyForSerialization() ) {
|
||||
if ( !jdbcCoordinator.isReadyForSerialization() ) {
|
||||
throw new IllegalStateException( "Cannot serialize a session while connected" );
|
||||
}
|
||||
|
||||
|
@ -2274,7 +2203,7 @@ public final class SessionImpl extends AbstractSessionImpl implements EventSourc
|
|||
factory.serialize( oos );
|
||||
oos.writeObject( sessionOwner );
|
||||
|
||||
transactionCoordinator.serialize( oos );
|
||||
jdbcCoordinator.serialize( oos );
|
||||
|
||||
persistenceContext.serialize( oos );
|
||||
actionQueue.serialize( oos );
|
||||
|
@ -2298,6 +2227,58 @@ public final class SessionImpl extends AbstractSessionImpl implements EventSourc
|
|||
|
||||
private transient LobHelperImpl lobHelper;
|
||||
|
||||
@Override
|
||||
public JdbcSessionContext getJdbcSessionContext() {
|
||||
return this.jdbcSessionContext;
|
||||
}
|
||||
|
||||
private StatementInspector getStatementInspector() {
|
||||
return this.interceptor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeTransactionCompletion() {
|
||||
LOG.trace( "before transaction completion" );
|
||||
flushBeforeTransactionCompletion();
|
||||
actionQueue.beforeTransactionCompletion();
|
||||
try {
|
||||
interceptor.beforeTransactionCompletion( currentHibernateTransaction );
|
||||
}
|
||||
catch (Throwable t) {
|
||||
LOG.exceptionInBeforeTransactionCompletionInterceptor( t );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterTransactionCompletion(boolean successful) {
|
||||
|
||||
LOG.trace( "after transaction completion" );
|
||||
|
||||
persistenceContext.afterTransactionCompletion();
|
||||
actionQueue.afterTransactionCompletion( successful );
|
||||
|
||||
getEventListenerManager().transactionCompletion( successful );
|
||||
|
||||
if ( factory.getStatistics().isStatisticsEnabled() ) {
|
||||
factory.getStatisticsImplementor().endTransaction( successful );
|
||||
}
|
||||
|
||||
try {
|
||||
interceptor.afterTransactionCompletion( currentHibernateTransaction );
|
||||
}
|
||||
catch (Throwable t) {
|
||||
LOG.exceptionInAfterTransactionCompletionInterceptor( t );
|
||||
}
|
||||
|
||||
if ( shouldAutoClose() && !isClosed() ) {
|
||||
managedClose();
|
||||
}
|
||||
|
||||
if ( autoClear ) {
|
||||
internalClear();
|
||||
}
|
||||
}
|
||||
|
||||
private static class LobHelperImpl implements LobHelper {
|
||||
private final SessionImpl session;
|
||||
|
||||
|
@ -2360,10 +2341,20 @@ public final class SessionImpl extends AbstractSessionImpl implements EventSourc
|
|||
}
|
||||
|
||||
@Override
|
||||
protected TransactionCoordinatorImpl getTransactionCoordinator() {
|
||||
protected TransactionCoordinator getTransactionCoordinator() {
|
||||
return shareTransactionContext ? session.transactionCoordinator : super.getTransactionCoordinator();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JdbcCoordinatorImpl getJdbcCoordinator() {
|
||||
return shareTransactionContext ? session.jdbcCoordinator : super.getJdbcCoordinator();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Transaction getTransaction() {
|
||||
return shareTransactionContext ? session.currentHibernateTransaction : super.getTransaction();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ActionQueue.TransactionCompletionProcesses getTransactionCompletionProcesses() {
|
||||
return shareTransactionContext ?
|
||||
|
@ -2844,4 +2835,33 @@ public final class SessionImpl extends AbstractSessionImpl implements EventSourc
|
|||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterTransactionBegin() {
|
||||
errorIfClosed();
|
||||
interceptor.afterTransactionBegin( currentHibernateTransaction );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void flushBeforeTransactionCompletion() {
|
||||
boolean flush = false;
|
||||
try {
|
||||
flush = (!isFlushModeNever() &&
|
||||
!flushBeforeCompletionEnabled) || (
|
||||
!isClosed()
|
||||
&& !isFlushModeNever()
|
||||
&& flushBeforeCompletionEnabled
|
||||
&& !JtaStatusHelper.isRollback(
|
||||
getSessionFactory().getSettings()
|
||||
.getJtaPlatform()
|
||||
.getCurrentStatus()
|
||||
));
|
||||
}
|
||||
catch (SystemException se) {
|
||||
throw new HibernateException( "could not determine transaction status in beforeCompletion()", se );
|
||||
}
|
||||
if ( flush ) {
|
||||
managedFlush();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
*/
|
||||
package org.hibernate.internal;
|
||||
|
||||
import javax.transaction.SystemException;
|
||||
import java.io.Serializable;
|
||||
import java.sql.Connection;
|
||||
import java.util.Collections;
|
||||
|
@ -30,8 +31,9 @@ import java.util.Iterator;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
import org.hibernate.CacheMode;
|
||||
import org.hibernate.ConnectionReleaseMode;
|
||||
import org.hibernate.Criteria;
|
||||
import org.hibernate.EmptyInterceptor;
|
||||
import org.hibernate.EntityMode;
|
||||
|
@ -51,6 +53,8 @@ import org.hibernate.collection.spi.PersistentCollection;
|
|||
import org.hibernate.engine.internal.SessionEventListenerManagerImpl;
|
||||
import org.hibernate.engine.internal.StatefulPersistenceContext;
|
||||
import org.hibernate.engine.internal.Versioning;
|
||||
import org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl;
|
||||
import org.hibernate.engine.jdbc.spi.JdbcCoordinator;
|
||||
import org.hibernate.engine.query.spi.HQLQueryPlan;
|
||||
import org.hibernate.engine.query.spi.NativeSQLQueryPlan;
|
||||
import org.hibernate.engine.query.spi.sql.NativeSQLQuerySpecification;
|
||||
|
@ -59,10 +63,7 @@ import org.hibernate.engine.spi.LoadQueryInfluencers;
|
|||
import org.hibernate.engine.spi.PersistenceContext;
|
||||
import org.hibernate.engine.spi.QueryParameters;
|
||||
import org.hibernate.engine.spi.SessionEventListenerManager;
|
||||
import org.hibernate.engine.transaction.internal.TransactionCoordinatorImpl;
|
||||
import org.hibernate.engine.transaction.spi.TransactionCoordinator;
|
||||
import org.hibernate.engine.transaction.spi.TransactionEnvironment;
|
||||
import org.hibernate.engine.transaction.spi.TransactionImplementor;
|
||||
import org.hibernate.engine.transaction.internal.jta.JtaStatusHelper;
|
||||
import org.hibernate.id.IdentifierGeneratorHelper;
|
||||
import org.hibernate.loader.criteria.CriteriaLoader;
|
||||
import org.hibernate.loader.custom.CustomLoader;
|
||||
|
@ -71,10 +72,11 @@ import org.hibernate.persister.entity.EntityPersister;
|
|||
import org.hibernate.persister.entity.OuterJoinLoadable;
|
||||
import org.hibernate.pretty.MessageHelper;
|
||||
import org.hibernate.proxy.HibernateProxy;
|
||||
import org.hibernate.resource.jdbc.spi.JdbcSessionContext;
|
||||
import org.hibernate.resource.transaction.TransactionCoordinator;
|
||||
import org.hibernate.resource.transaction.spi.TransactionStatus;
|
||||
import org.hibernate.type.Type;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
/**
|
||||
* @author Gavin King
|
||||
*/
|
||||
|
@ -83,9 +85,12 @@ public class StatelessSessionImpl extends AbstractSessionImpl implements Statele
|
|||
private static final CoreMessageLogger LOG = Logger.getMessageLogger(CoreMessageLogger.class, StatelessSessionImpl.class.getName());
|
||||
|
||||
private TransactionCoordinator transactionCoordinator;
|
||||
|
||||
private transient JdbcCoordinator jdbcCoordinator;
|
||||
private PersistenceContext temporaryPersistenceContext = new StatefulPersistenceContext( this );
|
||||
private long timestamp;
|
||||
|
||||
private JdbcSessionContext jdbcSessionContext;
|
||||
|
||||
StatelessSessionImpl(
|
||||
Connection connection,
|
||||
String tenantIdentifier,
|
||||
|
@ -99,20 +104,27 @@ public class StatelessSessionImpl extends AbstractSessionImpl implements Statele
|
|||
SessionFactoryImpl factory,
|
||||
long timestamp) {
|
||||
super( factory, tenantIdentifier );
|
||||
this.transactionCoordinator = new TransactionCoordinatorImpl( connection, this );
|
||||
this.jdbcSessionContext = new JdbcSessionContextImpl( factory, EmptyInterceptor.INSTANCE );
|
||||
this.jdbcCoordinator = new JdbcCoordinatorImpl( connection, this );
|
||||
|
||||
this.transactionCoordinator = getTransactionCoordinatorBuilder().buildTransactionCoordinator( jdbcCoordinator );
|
||||
this.currentHibernateTransaction = getTransaction();
|
||||
this.timestamp = timestamp;
|
||||
}
|
||||
|
||||
// TransactionContext ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
@Override
|
||||
public TransactionCoordinator getTransactionCoordinator() {
|
||||
return transactionCoordinator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TransactionEnvironment getTransactionEnvironment() {
|
||||
return factory.getTransactionEnvironment();
|
||||
public JdbcCoordinator getJdbcCoordinator() {
|
||||
return this.jdbcCoordinator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldAutoJoinTransaction() {
|
||||
return true;
|
||||
}
|
||||
|
||||
// inserts ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
@ -153,16 +165,16 @@ public class StatelessSessionImpl extends AbstractSessionImpl implements Statele
|
|||
@Override
|
||||
public void delete(Object entity) {
|
||||
errorIfClosed();
|
||||
delete(null, entity);
|
||||
delete( null, entity );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete(String entityName, Object entity) {
|
||||
errorIfClosed();
|
||||
EntityPersister persister = getEntityPersister(entityName, entity);
|
||||
EntityPersister persister = getEntityPersister( entityName, entity );
|
||||
Serializable id = persister.getIdentifier( entity, this );
|
||||
Object version = persister.getVersion( entity );
|
||||
persister.delete(id, version, entity, this);
|
||||
persister.delete( id, version, entity, this );
|
||||
}
|
||||
|
||||
|
||||
|
@ -343,69 +355,32 @@ public class StatelessSessionImpl extends AbstractSessionImpl implements Statele
|
|||
managedClose();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConnectionReleaseMode getConnectionReleaseMode() {
|
||||
return factory.getSettings().getConnectionReleaseMode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldAutoJoinTransaction() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAutoCloseSessionEnabled() {
|
||||
return factory.getSettings().isAutoCloseSessionEnabled();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFlushBeforeCompletionEnabled() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFlushModeNever() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void managedClose() {
|
||||
if ( isClosed() ) {
|
||||
throw new SessionException( "Session was already closed!" );
|
||||
}
|
||||
transactionCoordinator.close();
|
||||
setClosed();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void managedFlush() {
|
||||
errorIfClosed();
|
||||
getTransactionCoordinator().getJdbcCoordinator().executeBatch();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldAutoClose() {
|
||||
return isAutoCloseSessionEnabled() && !isClosed();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterTransactionBegin(TransactionImplementor hibernateTransaction) {
|
||||
// nothing to do here
|
||||
|
||||
private boolean isFlushModeNever() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeTransactionCompletion(TransactionImplementor hibernateTransaction) {
|
||||
// nothing to do here
|
||||
private void managedClose() {
|
||||
if ( isClosed() ) {
|
||||
throw new SessionException( "Session was already closed!" );
|
||||
}
|
||||
jdbcCoordinator.close();
|
||||
setClosed();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterTransactionCompletion(TransactionImplementor hibernateTransaction, boolean successful) {
|
||||
// nothing to do here
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onPrepareStatement(String sql) {
|
||||
return sql;
|
||||
private void managedFlush() {
|
||||
errorIfClosed();
|
||||
jdbcCoordinator.executeBatch();
|
||||
}
|
||||
|
||||
private SessionEventListenerManagerImpl sessionEventsManager;
|
||||
|
@ -418,30 +393,6 @@ public class StatelessSessionImpl extends AbstractSessionImpl implements Statele
|
|||
return sessionEventsManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startPrepareStatement() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endPrepareStatement() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startStatementExecution() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endStatementExecution() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startBatchExecution() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endBatchExecution() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String bestGuessEntityName(Object object) {
|
||||
if (object instanceof HibernateProxy) {
|
||||
|
@ -453,7 +404,7 @@ public class StatelessSessionImpl extends AbstractSessionImpl implements Statele
|
|||
@Override
|
||||
public Connection connection() {
|
||||
errorIfClosed();
|
||||
return transactionCoordinator.getJdbcCoordinator().getLogicalConnection().getConnection();
|
||||
return jdbcCoordinator.getLogicalConnection().getPhysicalConnection();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -556,12 +507,13 @@ public class StatelessSessionImpl extends AbstractSessionImpl implements Statele
|
|||
|
||||
@Override
|
||||
public boolean isConnected() {
|
||||
return transactionCoordinator.getJdbcCoordinator().getLogicalConnection().isPhysicallyConnected();
|
||||
return jdbcCoordinator.getLogicalConnection().isPhysicallyConnected();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isTransactionInProgress() {
|
||||
return transactionCoordinator.isTransactionInProgress();
|
||||
return !isClosed() && transactionCoordinator.isJoined() && transactionCoordinator.getTransactionDriverControl()
|
||||
.getStatus() == TransactionStatus.ACTIVE;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -584,12 +536,6 @@ public class StatelessSessionImpl extends AbstractSessionImpl implements Statele
|
|||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Transaction getTransaction() throws HibernateException {
|
||||
errorIfClosed();
|
||||
return transactionCoordinator.getTransaction();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Transaction beginTransaction() throws HibernateException {
|
||||
errorIfClosed();
|
||||
|
@ -636,8 +582,8 @@ public class StatelessSessionImpl extends AbstractSessionImpl implements Statele
|
|||
}
|
||||
|
||||
public void afterOperation(boolean success) {
|
||||
if ( ! transactionCoordinator.isTransactionInProgress() ) {
|
||||
transactionCoordinator.afterNonTransactionalQuery( success );
|
||||
if ( ! isTransactionInProgress() ) {
|
||||
jdbcCoordinator.afterTransaction();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -804,4 +750,48 @@ public class StatelessSessionImpl extends AbstractSessionImpl implements Statele
|
|||
temporaryPersistenceContext.clear();
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JdbcSessionContext getJdbcSessionContext() {
|
||||
return this.jdbcSessionContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterTransactionBegin() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeTransactionCompletion() {
|
||||
flushBeforeTransactionCompletion();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterTransactionCompletion(boolean successful) {
|
||||
if ( shouldAutoClose()
|
||||
&& !isClosed() ) {
|
||||
managedClose();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void flushBeforeTransactionCompletion() {
|
||||
boolean flush = false;
|
||||
try {
|
||||
flush = (
|
||||
!isClosed()
|
||||
&& !isFlushModeNever()
|
||||
&& !JtaStatusHelper.isRollback(
|
||||
factory.getSettings()
|
||||
.getJtaPlatform()
|
||||
.getCurrentStatus()
|
||||
));
|
||||
}
|
||||
catch (SystemException se) {
|
||||
throw new HibernateException( "could not determine transaction status in beforeCompletion()", se );
|
||||
}
|
||||
if ( flush ) {
|
||||
managedFlush();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,82 +0,0 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2011, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.internal;
|
||||
|
||||
import org.hibernate.engine.jdbc.spi.JdbcServices;
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.engine.transaction.jta.platform.spi.JtaPlatform;
|
||||
import org.hibernate.engine.transaction.spi.TransactionEnvironment;
|
||||
import org.hibernate.engine.transaction.spi.TransactionFactory;
|
||||
import org.hibernate.service.ServiceRegistry;
|
||||
import org.hibernate.stat.spi.StatisticsImplementor;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class TransactionEnvironmentImpl implements TransactionEnvironment {
|
||||
private final SessionFactoryImpl sessionFactory;
|
||||
private final transient StatisticsImplementor statisticsImplementor;
|
||||
private final transient ServiceRegistry serviceRegistry;
|
||||
private final transient JdbcServices jdbcServices;
|
||||
private final transient JtaPlatform jtaPlatform;
|
||||
private final transient TransactionFactory transactionFactory;
|
||||
|
||||
public TransactionEnvironmentImpl(SessionFactoryImpl sessionFactory) {
|
||||
this.sessionFactory = sessionFactory;
|
||||
this.statisticsImplementor = sessionFactory.getStatisticsImplementor();
|
||||
this.serviceRegistry = sessionFactory.getServiceRegistry();
|
||||
this.jdbcServices = serviceRegistry.getService( JdbcServices.class );
|
||||
this.jtaPlatform = serviceRegistry.getService( JtaPlatform.class );
|
||||
this.transactionFactory = serviceRegistry.getService( TransactionFactory.class );
|
||||
}
|
||||
|
||||
@Override
|
||||
public SessionFactoryImplementor getSessionFactory() {
|
||||
return sessionFactory;
|
||||
}
|
||||
|
||||
protected ServiceRegistry serviceRegistry() {
|
||||
return serviceRegistry;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JdbcServices getJdbcServices() {
|
||||
return jdbcServices;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JtaPlatform getJtaPlatform() {
|
||||
return jtaPlatform;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TransactionFactory getTransactionFactory() {
|
||||
return transactionFactory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public StatisticsImplementor getStatisticsImplementor() {
|
||||
return statisticsImplementor;
|
||||
}
|
||||
}
|
|
@ -921,7 +921,8 @@ public abstract class Loader {
|
|||
return processResultSet( rs, queryParameters, session, returnProxies, forcedResultTransformer, maxRows, afterLoadActions );
|
||||
}
|
||||
finally {
|
||||
session.getTransactionCoordinator().getJdbcCoordinator().release( st );
|
||||
session.getJdbcCoordinator().getResourceRegistry().release( st );
|
||||
session.getJdbcCoordinator().afterStatementExecution();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1880,7 +1881,7 @@ public abstract class Loader {
|
|||
boolean callable = queryParameters.isCallable();
|
||||
final ScrollMode scrollMode = getScrollMode( scroll, hasFirstRow, useLimitOffset, queryParameters );
|
||||
|
||||
PreparedStatement st = session.getTransactionCoordinator().getJdbcCoordinator().getStatementPreparer().prepareQueryStatement(
|
||||
PreparedStatement st = session.getJdbcCoordinator().getStatementPreparer().prepareQueryStatement(
|
||||
sql,
|
||||
callable,
|
||||
scrollMode
|
||||
|
@ -1933,11 +1934,13 @@ public abstract class Loader {
|
|||
LOG.tracev( "Bound [{0}] parameters total", col );
|
||||
}
|
||||
catch ( SQLException sqle ) {
|
||||
session.getTransactionCoordinator().getJdbcCoordinator().release( st );
|
||||
session.getJdbcCoordinator().getResourceRegistry().release( st );
|
||||
session.getJdbcCoordinator().afterStatementExecution();
|
||||
throw sqle;
|
||||
}
|
||||
catch ( HibernateException he ) {
|
||||
session.getTransactionCoordinator().getJdbcCoordinator().release( st );
|
||||
session.getJdbcCoordinator().getResourceRegistry().release( st );
|
||||
session.getJdbcCoordinator().afterStatementExecution();
|
||||
throw he;
|
||||
}
|
||||
|
||||
|
@ -2061,7 +2064,7 @@ public abstract class Loader {
|
|||
throws SQLException, HibernateException {
|
||||
|
||||
try {
|
||||
ResultSet rs = session.getTransactionCoordinator().getJdbcCoordinator().getResultSetReturn().extract( st );
|
||||
ResultSet rs = session.getJdbcCoordinator().getResultSetReturn().extract( st );
|
||||
rs = wrapResultSetIfEnabled( rs , session );
|
||||
|
||||
if ( !limitHandler.supportsLimitOffset() || !LimitHelper.useLimit( limitHandler, selection ) ) {
|
||||
|
@ -2074,7 +2077,8 @@ public abstract class Loader {
|
|||
return rs;
|
||||
}
|
||||
catch ( SQLException sqle ) {
|
||||
session.getTransactionCoordinator().getJdbcCoordinator().release( st );
|
||||
session.getJdbcCoordinator().getResourceRegistry().release( st );
|
||||
session.getJdbcCoordinator().afterStatementExecution();
|
||||
throw sqle;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -261,7 +261,8 @@ public class DynamicBatchingCollectionInitializerBuilder extends BatchingCollect
|
|||
processResultSet( rs, queryParameters, session, true, null, maxRows, afterLoadActions );
|
||||
}
|
||||
finally {
|
||||
session.getTransactionCoordinator().getJdbcCoordinator().release( st );
|
||||
session.getJdbcCoordinator().getResourceRegistry().release( st );
|
||||
session.getJdbcCoordinator().afterStatementExecution();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -263,7 +263,8 @@ public class DynamicBatchingEntityLoaderBuilder extends BatchingEntityLoaderBuil
|
|||
return processResultSet( rs, queryParameters, session, false, null, maxRows, afterLoadActions );
|
||||
}
|
||||
finally {
|
||||
session.getTransactionCoordinator().getJdbcCoordinator().release( st );
|
||||
session.getJdbcCoordinator().getResourceRegistry().release( st );
|
||||
session.getJdbcCoordinator().afterStatementExecution();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -153,11 +153,12 @@ public abstract class AbstractLoadPlanBasedLoader {
|
|||
}
|
||||
finally {
|
||||
if ( wrapper != null ) {
|
||||
session.getTransactionCoordinator().getJdbcCoordinator().release(
|
||||
session.getJdbcCoordinator().getResourceRegistry().release(
|
||||
wrapper.getResultSet(),
|
||||
wrapper.getStatement()
|
||||
);
|
||||
session.getTransactionCoordinator().getJdbcCoordinator().release( wrapper.getStatement() );
|
||||
session.getJdbcCoordinator().getResourceRegistry().release( wrapper.getStatement() );
|
||||
session.getJdbcCoordinator().afterStatementExecution();
|
||||
}
|
||||
persistenceContext.afterLoad();
|
||||
}
|
||||
|
@ -252,7 +253,7 @@ public abstract class AbstractLoadPlanBasedLoader {
|
|||
final boolean callable = queryParameters.isCallable();
|
||||
final ScrollMode scrollMode = getScrollMode( scroll, hasFirstRow, useLimitOffset, queryParameters );
|
||||
|
||||
final PreparedStatement st = session.getTransactionCoordinator().getJdbcCoordinator()
|
||||
final PreparedStatement st = session.getJdbcCoordinator()
|
||||
.getStatementPreparer().prepareQueryStatement( sql, callable, scrollMode );
|
||||
|
||||
try {
|
||||
|
@ -303,11 +304,13 @@ public abstract class AbstractLoadPlanBasedLoader {
|
|||
}
|
||||
}
|
||||
catch ( SQLException sqle ) {
|
||||
session.getTransactionCoordinator().getJdbcCoordinator().release( st );
|
||||
session.getJdbcCoordinator().getResourceRegistry().release( st );
|
||||
session.getJdbcCoordinator().afterStatementExecution();
|
||||
throw sqle;
|
||||
}
|
||||
catch ( HibernateException he ) {
|
||||
session.getTransactionCoordinator().getJdbcCoordinator().release( st );
|
||||
session.getJdbcCoordinator().getResourceRegistry().release( st );
|
||||
session.getJdbcCoordinator().afterStatementExecution();
|
||||
throw he;
|
||||
}
|
||||
|
||||
|
@ -444,7 +447,7 @@ public abstract class AbstractLoadPlanBasedLoader {
|
|||
throws SQLException, HibernateException {
|
||||
|
||||
try {
|
||||
ResultSet rs = session.getTransactionCoordinator().getJdbcCoordinator().getResultSetReturn().extract( st );
|
||||
ResultSet rs = session.getJdbcCoordinator().getResultSetReturn().extract( st );
|
||||
rs = wrapResultSetIfEnabled( rs , session );
|
||||
|
||||
if ( !limitHandler.supportsLimitOffset() || !LimitHelper.useLimit( limitHandler, selection ) ) {
|
||||
|
@ -457,7 +460,8 @@ public abstract class AbstractLoadPlanBasedLoader {
|
|||
return rs;
|
||||
}
|
||||
catch ( SQLException sqle ) {
|
||||
session.getTransactionCoordinator().getJdbcCoordinator().release( st );
|
||||
session.getJdbcCoordinator().getResourceRegistry().release( st );
|
||||
session.getJdbcCoordinator().afterStatementExecution();
|
||||
throw sqle;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1190,13 +1190,13 @@ public abstract class AbstractCollectionPersister
|
|||
expectation
|
||||
);
|
||||
}
|
||||
st = session.getTransactionCoordinator()
|
||||
st = session
|
||||
.getJdbcCoordinator()
|
||||
.getBatch( removeBatchKey )
|
||||
.getBatchStatement( sql, callable );
|
||||
}
|
||||
else {
|
||||
st = session.getTransactionCoordinator()
|
||||
st = session
|
||||
.getJdbcCoordinator()
|
||||
.getStatementPreparer()
|
||||
.prepareStatement( sql, callable );
|
||||
|
@ -1207,24 +1207,25 @@ public abstract class AbstractCollectionPersister
|
|||
|
||||
writeKey( st, id, offset, session );
|
||||
if ( useBatch ) {
|
||||
session.getTransactionCoordinator()
|
||||
session
|
||||
.getJdbcCoordinator()
|
||||
.getBatch( removeBatchKey )
|
||||
.addToBatch();
|
||||
}
|
||||
else {
|
||||
expectation.verifyOutcome( session.getTransactionCoordinator().getJdbcCoordinator().getResultSetReturn().executeUpdate( st ), st, -1 );
|
||||
expectation.verifyOutcome( session.getJdbcCoordinator().getResultSetReturn().executeUpdate( st ), st, -1 );
|
||||
}
|
||||
}
|
||||
catch ( SQLException sqle ) {
|
||||
if ( useBatch ) {
|
||||
session.getTransactionCoordinator().getJdbcCoordinator().abortBatch();
|
||||
session.getJdbcCoordinator().abortBatch();
|
||||
}
|
||||
throw sqle;
|
||||
}
|
||||
finally {
|
||||
if ( !useBatch ) {
|
||||
session.getTransactionCoordinator().getJdbcCoordinator().release( st );
|
||||
session.getJdbcCoordinator().getResourceRegistry().release( st );
|
||||
session.getJdbcCoordinator().afterStatementExecution();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1290,13 +1291,13 @@ public abstract class AbstractCollectionPersister
|
|||
expectation
|
||||
);
|
||||
}
|
||||
st = session.getTransactionCoordinator()
|
||||
st = session
|
||||
.getJdbcCoordinator()
|
||||
.getBatch( recreateBatchKey )
|
||||
.getBatchStatement( sql, callable );
|
||||
}
|
||||
else {
|
||||
st = session.getTransactionCoordinator()
|
||||
st = session
|
||||
.getJdbcCoordinator()
|
||||
.getStatementPreparer()
|
||||
.prepareStatement( sql, callable );
|
||||
|
@ -1316,13 +1317,13 @@ public abstract class AbstractCollectionPersister
|
|||
loc = writeElement( st, collection.getElement( entry ), loc, session );
|
||||
|
||||
if ( useBatch ) {
|
||||
session.getTransactionCoordinator()
|
||||
session
|
||||
.getJdbcCoordinator()
|
||||
.getBatch( recreateBatchKey )
|
||||
.addToBatch();
|
||||
}
|
||||
else {
|
||||
expectation.verifyOutcome( session.getTransactionCoordinator().getJdbcCoordinator().getResultSetReturn().executeUpdate( st ), st, -1 );
|
||||
expectation.verifyOutcome( session.getJdbcCoordinator().getResultSetReturn().executeUpdate( st ), st, -1 );
|
||||
}
|
||||
|
||||
collection.afterRowInsert( this, entry, i );
|
||||
|
@ -1330,13 +1331,14 @@ public abstract class AbstractCollectionPersister
|
|||
}
|
||||
catch ( SQLException sqle ) {
|
||||
if ( useBatch ) {
|
||||
session.getTransactionCoordinator().getJdbcCoordinator().abortBatch();
|
||||
session.getJdbcCoordinator().abortBatch();
|
||||
}
|
||||
throw sqle;
|
||||
}
|
||||
finally {
|
||||
if ( !useBatch ) {
|
||||
session.getTransactionCoordinator().getJdbcCoordinator().release( st );
|
||||
session.getJdbcCoordinator().getResourceRegistry().release( st );
|
||||
session.getJdbcCoordinator().afterStatementExecution();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1407,13 +1409,13 @@ public abstract class AbstractCollectionPersister
|
|||
expectation
|
||||
);
|
||||
}
|
||||
st = session.getTransactionCoordinator()
|
||||
st = session
|
||||
.getJdbcCoordinator()
|
||||
.getBatch( deleteBatchKey )
|
||||
.getBatchStatement( sql, callable );
|
||||
}
|
||||
else {
|
||||
st = session.getTransactionCoordinator()
|
||||
st = session
|
||||
.getJdbcCoordinator()
|
||||
.getStatementPreparer()
|
||||
.prepareStatement( sql, callable );
|
||||
|
@ -1438,25 +1440,26 @@ public abstract class AbstractCollectionPersister
|
|||
}
|
||||
|
||||
if ( useBatch ) {
|
||||
session.getTransactionCoordinator()
|
||||
session
|
||||
.getJdbcCoordinator()
|
||||
.getBatch( deleteBatchKey )
|
||||
.addToBatch();
|
||||
}
|
||||
else {
|
||||
expectation.verifyOutcome( session.getTransactionCoordinator().getJdbcCoordinator().getResultSetReturn().executeUpdate( st ), st, -1 );
|
||||
expectation.verifyOutcome( session.getJdbcCoordinator().getResultSetReturn().executeUpdate( st ), st, -1 );
|
||||
}
|
||||
count++;
|
||||
}
|
||||
catch ( SQLException sqle ) {
|
||||
if ( useBatch ) {
|
||||
session.getTransactionCoordinator().getJdbcCoordinator().abortBatch();
|
||||
session.getJdbcCoordinator().abortBatch();
|
||||
}
|
||||
throw sqle;
|
||||
}
|
||||
finally {
|
||||
if ( !useBatch ) {
|
||||
session.getTransactionCoordinator().getJdbcCoordinator().release( st );
|
||||
session.getJdbcCoordinator().getResourceRegistry().release( st );
|
||||
session.getJdbcCoordinator().afterStatementExecution();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1526,14 +1529,14 @@ public abstract class AbstractCollectionPersister
|
|||
);
|
||||
}
|
||||
if ( st == null ) {
|
||||
st = session.getTransactionCoordinator()
|
||||
st = session
|
||||
.getJdbcCoordinator()
|
||||
.getBatch( insertBatchKey )
|
||||
.getBatchStatement( sql, callable );
|
||||
}
|
||||
}
|
||||
else {
|
||||
st = session.getTransactionCoordinator()
|
||||
st = session
|
||||
.getJdbcCoordinator()
|
||||
.getStatementPreparer()
|
||||
.prepareStatement( sql, callable );
|
||||
|
@ -1552,23 +1555,24 @@ public abstract class AbstractCollectionPersister
|
|||
writeElement( st, collection.getElement( entry ), offset, session );
|
||||
|
||||
if ( useBatch ) {
|
||||
session.getTransactionCoordinator().getJdbcCoordinator().getBatch( insertBatchKey ).addToBatch();
|
||||
session.getJdbcCoordinator().getBatch( insertBatchKey ).addToBatch();
|
||||
}
|
||||
else {
|
||||
expectation.verifyOutcome( session.getTransactionCoordinator().getJdbcCoordinator().getResultSetReturn().executeUpdate( st ), st, -1 );
|
||||
expectation.verifyOutcome( session.getJdbcCoordinator().getResultSetReturn().executeUpdate( st ), st, -1 );
|
||||
}
|
||||
collection.afterRowInsert( this, entry, i );
|
||||
count++;
|
||||
}
|
||||
catch ( SQLException sqle ) {
|
||||
if ( useBatch ) {
|
||||
session.getTransactionCoordinator().getJdbcCoordinator().abortBatch();
|
||||
session.getJdbcCoordinator().abortBatch();
|
||||
}
|
||||
throw sqle;
|
||||
}
|
||||
finally {
|
||||
if ( !useBatch ) {
|
||||
session.getTransactionCoordinator().getJdbcCoordinator().release( st );
|
||||
session.getJdbcCoordinator().getResourceRegistry().release( st );
|
||||
session.getJdbcCoordinator().afterStatementExecution();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1936,22 +1940,23 @@ public abstract class AbstractCollectionPersister
|
|||
@Override
|
||||
public int getSize(Serializable key, SessionImplementor session) {
|
||||
try {
|
||||
PreparedStatement st = session.getTransactionCoordinator()
|
||||
PreparedStatement st = session
|
||||
.getJdbcCoordinator()
|
||||
.getStatementPreparer()
|
||||
.prepareStatement( sqlSelectSizeString );
|
||||
try {
|
||||
getKeyType().nullSafeSet( st, key, 1, session );
|
||||
ResultSet rs = session.getTransactionCoordinator().getJdbcCoordinator().getResultSetReturn().extract( st );
|
||||
ResultSet rs = session.getJdbcCoordinator().getResultSetReturn().extract( st );
|
||||
try {
|
||||
return rs.next() ? rs.getInt( 1 ) - baseIndex : 0;
|
||||
}
|
||||
finally {
|
||||
session.getTransactionCoordinator().getJdbcCoordinator().release( rs, st );
|
||||
session.getJdbcCoordinator().getResourceRegistry().release( rs, st );
|
||||
}
|
||||
}
|
||||
finally {
|
||||
session.getTransactionCoordinator().getJdbcCoordinator().release( st );
|
||||
session.getJdbcCoordinator().getResourceRegistry().release( st );
|
||||
session.getJdbcCoordinator().afterStatementExecution();
|
||||
}
|
||||
}
|
||||
catch ( SQLException sqle ) {
|
||||
|
@ -1976,26 +1981,27 @@ public abstract class AbstractCollectionPersister
|
|||
|
||||
private boolean exists(Serializable key, Object indexOrElement, Type indexOrElementType, String sql, SessionImplementor session) {
|
||||
try {
|
||||
PreparedStatement st = session.getTransactionCoordinator()
|
||||
PreparedStatement st = session
|
||||
.getJdbcCoordinator()
|
||||
.getStatementPreparer()
|
||||
.prepareStatement( sql );
|
||||
try {
|
||||
getKeyType().nullSafeSet( st, key, 1, session );
|
||||
indexOrElementType.nullSafeSet( st, indexOrElement, keyColumnNames.length + 1, session );
|
||||
ResultSet rs = session.getTransactionCoordinator().getJdbcCoordinator().getResultSetReturn().extract( st );
|
||||
ResultSet rs = session.getJdbcCoordinator().getResultSetReturn().extract( st );
|
||||
try {
|
||||
return rs.next();
|
||||
}
|
||||
finally {
|
||||
session.getTransactionCoordinator().getJdbcCoordinator().release( rs, st );
|
||||
session.getJdbcCoordinator().getResourceRegistry().release( rs, st );
|
||||
}
|
||||
}
|
||||
catch ( TransientObjectException e ) {
|
||||
return false;
|
||||
}
|
||||
finally {
|
||||
session.getTransactionCoordinator().getJdbcCoordinator().release( st );
|
||||
session.getJdbcCoordinator().getResourceRegistry().release( st );
|
||||
session.getJdbcCoordinator().afterStatementExecution();
|
||||
}
|
||||
}
|
||||
catch ( SQLException sqle ) {
|
||||
|
@ -2011,14 +2017,14 @@ public abstract class AbstractCollectionPersister
|
|||
@Override
|
||||
public Object getElementByIndex(Serializable key, Object index, SessionImplementor session, Object owner) {
|
||||
try {
|
||||
PreparedStatement st = session.getTransactionCoordinator()
|
||||
PreparedStatement st = session
|
||||
.getJdbcCoordinator()
|
||||
.getStatementPreparer()
|
||||
.prepareStatement( sqlSelectRowByIndexString );
|
||||
try {
|
||||
getKeyType().nullSafeSet( st, key, 1, session );
|
||||
getIndexType().nullSafeSet( st, incrementIndexByBase( index ), keyColumnNames.length + 1, session );
|
||||
ResultSet rs = session.getTransactionCoordinator().getJdbcCoordinator().getResultSetReturn().extract( st );
|
||||
ResultSet rs = session.getJdbcCoordinator().getResultSetReturn().extract( st );
|
||||
try {
|
||||
if ( rs.next() ) {
|
||||
return getElementType().nullSafeGet( rs, elementColumnAliases, session, owner );
|
||||
|
@ -2028,11 +2034,12 @@ public abstract class AbstractCollectionPersister
|
|||
}
|
||||
}
|
||||
finally {
|
||||
session.getTransactionCoordinator().getJdbcCoordinator().release( rs, st );
|
||||
session.getJdbcCoordinator().getResourceRegistry().release( rs, st );
|
||||
}
|
||||
}
|
||||
finally {
|
||||
session.getTransactionCoordinator().getJdbcCoordinator().release( st );
|
||||
session.getJdbcCoordinator().getResourceRegistry().release( st );
|
||||
session.getJdbcCoordinator().afterStatementExecution();
|
||||
}
|
||||
}
|
||||
catch ( SQLException sqle ) {
|
||||
|
|
|
@ -232,13 +232,13 @@ public class BasicCollectionPersister extends AbstractCollectionPersister {
|
|||
expectation
|
||||
);
|
||||
}
|
||||
st = session.getTransactionCoordinator()
|
||||
st = session
|
||||
.getJdbcCoordinator()
|
||||
.getBatch( updateBatchKey )
|
||||
.getBatchStatement( sql, callable );
|
||||
}
|
||||
else {
|
||||
st = session.getTransactionCoordinator()
|
||||
st = session
|
||||
.getJdbcCoordinator()
|
||||
.getStatementPreparer()
|
||||
.prepareStatement( sql, callable );
|
||||
|
@ -261,24 +261,25 @@ public class BasicCollectionPersister extends AbstractCollectionPersister {
|
|||
}
|
||||
|
||||
if ( useBatch ) {
|
||||
session.getTransactionCoordinator()
|
||||
session
|
||||
.getJdbcCoordinator()
|
||||
.getBatch( updateBatchKey )
|
||||
.addToBatch();
|
||||
}
|
||||
else {
|
||||
expectation.verifyOutcome( session.getTransactionCoordinator().getJdbcCoordinator().getResultSetReturn().executeUpdate( st ), st, -1 );
|
||||
expectation.verifyOutcome( session.getJdbcCoordinator().getResultSetReturn().executeUpdate( st ), st, -1 );
|
||||
}
|
||||
}
|
||||
catch ( SQLException sqle ) {
|
||||
if ( useBatch ) {
|
||||
session.getTransactionCoordinator().getJdbcCoordinator().abortBatch();
|
||||
session.getJdbcCoordinator().abortBatch();
|
||||
}
|
||||
throw sqle;
|
||||
}
|
||||
finally {
|
||||
if ( !useBatch ) {
|
||||
session.getTransactionCoordinator().getJdbcCoordinator().release( st );
|
||||
session.getJdbcCoordinator().getResourceRegistry().release( st );
|
||||
session.getJdbcCoordinator().afterStatementExecution();
|
||||
}
|
||||
}
|
||||
count++;
|
||||
|
|
|
@ -225,13 +225,13 @@ public class OneToManyPersister extends AbstractCollectionPersister {
|
|||
expectation
|
||||
);
|
||||
}
|
||||
st = session.getTransactionCoordinator()
|
||||
st = session
|
||||
.getJdbcCoordinator()
|
||||
.getBatch( recreateBatchKey )
|
||||
.getBatchStatement( sql, callable );
|
||||
}
|
||||
else {
|
||||
st = session.getTransactionCoordinator()
|
||||
st = session
|
||||
.getJdbcCoordinator()
|
||||
.getStatementPreparer()
|
||||
.prepareStatement( sql, callable );
|
||||
|
@ -246,24 +246,25 @@ public class OneToManyPersister extends AbstractCollectionPersister {
|
|||
offset = writeElement( st, collection.getElement( entry ), offset, session );
|
||||
|
||||
if ( useBatch ) {
|
||||
session.getTransactionCoordinator()
|
||||
session
|
||||
.getJdbcCoordinator()
|
||||
.getBatch( recreateBatchKey )
|
||||
.addToBatch();
|
||||
}
|
||||
else {
|
||||
expectation.verifyOutcome( session.getTransactionCoordinator().getJdbcCoordinator().getResultSetReturn().executeUpdate( st ), st, -1 );
|
||||
expectation.verifyOutcome( session.getJdbcCoordinator().getResultSetReturn().executeUpdate( st ), st, -1 );
|
||||
}
|
||||
}
|
||||
catch ( SQLException sqle ) {
|
||||
if ( useBatch ) {
|
||||
session.getTransactionCoordinator().getJdbcCoordinator().abortBatch();
|
||||
session.getJdbcCoordinator().abortBatch();
|
||||
}
|
||||
throw sqle;
|
||||
}
|
||||
finally {
|
||||
if ( !useBatch ) {
|
||||
session.getTransactionCoordinator().getJdbcCoordinator().release( st );
|
||||
session.getJdbcCoordinator().getResourceRegistry().release( st );
|
||||
session.getJdbcCoordinator().afterStatementExecution();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -331,13 +332,13 @@ public class OneToManyPersister extends AbstractCollectionPersister {
|
|||
Object entry = entries.next();
|
||||
if ( collection.needsUpdating( entry, i, elementType ) ) { // will still be issued when it used to be null
|
||||
if ( useBatch ) {
|
||||
st = session.getTransactionCoordinator()
|
||||
st = session
|
||||
.getJdbcCoordinator()
|
||||
.getBatch( deleteRowBatchKey )
|
||||
.getBatchStatement( sql, isDeleteCallable() );
|
||||
}
|
||||
else {
|
||||
st = session.getTransactionCoordinator()
|
||||
st = session
|
||||
.getJdbcCoordinator()
|
||||
.getStatementPreparer()
|
||||
.prepareStatement( sql, isDeleteCallable() );
|
||||
|
@ -345,13 +346,13 @@ public class OneToManyPersister extends AbstractCollectionPersister {
|
|||
int loc = writeKey( st, id, offset, session );
|
||||
writeElementToWhere( st, collection.getSnapshotElement(entry, i), loc, session );
|
||||
if ( useBatch ) {
|
||||
session.getTransactionCoordinator()
|
||||
session
|
||||
.getJdbcCoordinator()
|
||||
.getBatch( deleteRowBatchKey )
|
||||
.addToBatch();
|
||||
}
|
||||
else {
|
||||
deleteExpectation.verifyOutcome( session.getTransactionCoordinator().getJdbcCoordinator().getResultSetReturn().executeUpdate( st ), st, -1 );
|
||||
deleteExpectation.verifyOutcome( session.getJdbcCoordinator().getResultSetReturn().executeUpdate( st ), st, -1 );
|
||||
}
|
||||
count++;
|
||||
}
|
||||
|
@ -360,13 +361,14 @@ public class OneToManyPersister extends AbstractCollectionPersister {
|
|||
}
|
||||
catch ( SQLException e ) {
|
||||
if ( useBatch ) {
|
||||
session.getTransactionCoordinator().getJdbcCoordinator().abortBatch();
|
||||
session.getJdbcCoordinator().abortBatch();
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
finally {
|
||||
if ( !useBatch ) {
|
||||
session.getTransactionCoordinator().getJdbcCoordinator().release( st );
|
||||
session.getJdbcCoordinator().getResourceRegistry().release( st );
|
||||
session.getJdbcCoordinator().afterStatementExecution();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -393,13 +395,13 @@ public class OneToManyPersister extends AbstractCollectionPersister {
|
|||
int offset = 1;
|
||||
if ( collection.needsUpdating( entry, i, elementType ) ) {
|
||||
if ( useBatch ) {
|
||||
st = session.getTransactionCoordinator()
|
||||
st = session
|
||||
.getJdbcCoordinator()
|
||||
.getBatch( insertRowBatchKey )
|
||||
.getBatchStatement( sql, callable );
|
||||
}
|
||||
else {
|
||||
st = session.getTransactionCoordinator()
|
||||
st = session
|
||||
.getJdbcCoordinator()
|
||||
.getStatementPreparer()
|
||||
.prepareStatement( sql, callable );
|
||||
|
@ -415,10 +417,10 @@ public class OneToManyPersister extends AbstractCollectionPersister {
|
|||
writeElementToWhere( st, collection.getElement( entry ), loc, session );
|
||||
|
||||
if ( useBatch ) {
|
||||
session.getTransactionCoordinator().getJdbcCoordinator().getBatch( insertRowBatchKey ).addToBatch();
|
||||
session.getJdbcCoordinator().getBatch( insertRowBatchKey ).addToBatch();
|
||||
}
|
||||
else {
|
||||
insertExpectation.verifyOutcome( session.getTransactionCoordinator().getJdbcCoordinator().getResultSetReturn().executeUpdate( st ), st, -1 );
|
||||
insertExpectation.verifyOutcome( session.getJdbcCoordinator().getResultSetReturn().executeUpdate( st ), st, -1 );
|
||||
}
|
||||
count++;
|
||||
}
|
||||
|
@ -427,13 +429,14 @@ public class OneToManyPersister extends AbstractCollectionPersister {
|
|||
}
|
||||
catch ( SQLException sqle ) {
|
||||
if ( useBatch ) {
|
||||
session.getTransactionCoordinator().getJdbcCoordinator().abortBatch();
|
||||
session.getJdbcCoordinator().abortBatch();
|
||||
}
|
||||
throw sqle;
|
||||
}
|
||||
finally {
|
||||
if ( !useBatch ) {
|
||||
session.getTransactionCoordinator().getJdbcCoordinator().release( st );
|
||||
session.getJdbcCoordinator().getResourceRegistry().release( st );
|
||||
session.getJdbcCoordinator().afterStatementExecution();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -938,12 +938,11 @@ public abstract class AbstractEntityPersister
|
|||
// null sql means that the only lazy properties
|
||||
// are shared PK one-to-one associations which are
|
||||
// handled differently in the Type#nullSafeGet code...
|
||||
ps = session.getTransactionCoordinator()
|
||||
.getJdbcCoordinator()
|
||||
ps = session.getJdbcCoordinator()
|
||||
.getStatementPreparer()
|
||||
.prepareStatement( lazySelect );
|
||||
getIdentifierType().nullSafeSet( ps, id, 1, session );
|
||||
rs = session.getTransactionCoordinator().getJdbcCoordinator().getResultSetReturn().extract( ps );
|
||||
rs = session.getJdbcCoordinator().getResultSetReturn().extract( ps );
|
||||
rs.next();
|
||||
}
|
||||
final Object[] snapshot = entry.getLoadedState();
|
||||
|
@ -956,13 +955,14 @@ public abstract class AbstractEntityPersister
|
|||
}
|
||||
finally {
|
||||
if ( rs != null ) {
|
||||
session.getTransactionCoordinator().getJdbcCoordinator().release( rs, ps );
|
||||
session.getJdbcCoordinator().getResourceRegistry().release( rs, ps );
|
||||
}
|
||||
}
|
||||
}
|
||||
finally {
|
||||
if ( ps != null ) {
|
||||
session.getTransactionCoordinator().getJdbcCoordinator().release( ps );
|
||||
session.getJdbcCoordinator().getResourceRegistry().release( ps );
|
||||
session.getJdbcCoordinator().afterStatementExecution();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1188,14 +1188,14 @@ public abstract class AbstractEntityPersister
|
|||
}
|
||||
|
||||
try {
|
||||
PreparedStatement ps = session.getTransactionCoordinator()
|
||||
PreparedStatement ps = session
|
||||
.getJdbcCoordinator()
|
||||
.getStatementPreparer()
|
||||
.prepareStatement( getSQLSnapshotSelectString() );
|
||||
try {
|
||||
getIdentifierType().nullSafeSet( ps, id, 1, session );
|
||||
//if ( isVersioned() ) getVersionType().nullSafeSet( ps, version, getIdentifierColumnSpan()+1, session );
|
||||
ResultSet rs = session.getTransactionCoordinator().getJdbcCoordinator().getResultSetReturn().extract( ps );
|
||||
ResultSet rs = session.getJdbcCoordinator().getResultSetReturn().extract( ps );
|
||||
try {
|
||||
//if there is no resulting row, return null
|
||||
if ( !rs.next() ) {
|
||||
|
@ -1213,11 +1213,12 @@ public abstract class AbstractEntityPersister
|
|||
return values;
|
||||
}
|
||||
finally {
|
||||
session.getTransactionCoordinator().getJdbcCoordinator().release( rs, ps );
|
||||
session.getJdbcCoordinator().getResourceRegistry().release( rs, ps );
|
||||
}
|
||||
}
|
||||
finally {
|
||||
session.getTransactionCoordinator().getJdbcCoordinator().release( ps );
|
||||
session.getJdbcCoordinator().getResourceRegistry().release( ps );
|
||||
session.getJdbcCoordinator().afterStatementExecution();
|
||||
}
|
||||
}
|
||||
catch ( SQLException e ) {
|
||||
|
@ -1249,13 +1250,13 @@ public abstract class AbstractEntityPersister
|
|||
Type propertyType = getSubclassPropertyType( propertyIndex );
|
||||
|
||||
try {
|
||||
PreparedStatement ps = session.getTransactionCoordinator()
|
||||
PreparedStatement ps = session
|
||||
.getJdbcCoordinator()
|
||||
.getStatementPreparer()
|
||||
.prepareStatement( generateIdByUniqueKeySelectString( uniquePropertyName ) );
|
||||
try {
|
||||
propertyType.nullSafeSet( ps, key, 1, session );
|
||||
ResultSet rs = session.getTransactionCoordinator().getJdbcCoordinator().getResultSetReturn().extract( ps );
|
||||
ResultSet rs = session.getJdbcCoordinator().getResultSetReturn().extract( ps );
|
||||
try {
|
||||
//if there is no resulting row, return null
|
||||
if ( !rs.next() ) {
|
||||
|
@ -1264,11 +1265,12 @@ public abstract class AbstractEntityPersister
|
|||
return (Serializable) getIdentifierType().nullSafeGet( rs, getIdentifierAliases(), session, null );
|
||||
}
|
||||
finally {
|
||||
session.getTransactionCoordinator().getJdbcCoordinator().release( rs, ps );
|
||||
session.getJdbcCoordinator().getResourceRegistry().release( rs, ps );
|
||||
}
|
||||
}
|
||||
finally {
|
||||
session.getTransactionCoordinator().getJdbcCoordinator().release( ps );
|
||||
session.getJdbcCoordinator().getResourceRegistry().release( ps );
|
||||
session.getJdbcCoordinator().afterStatementExecution();
|
||||
}
|
||||
}
|
||||
catch ( SQLException e ) {
|
||||
|
@ -1496,7 +1498,7 @@ public abstract class AbstractEntityPersister
|
|||
String versionIncrementString = generateVersionIncrementUpdateString();
|
||||
PreparedStatement st = null;
|
||||
try {
|
||||
st = session.getTransactionCoordinator()
|
||||
st = session
|
||||
.getJdbcCoordinator()
|
||||
.getStatementPreparer()
|
||||
.prepareStatement( versionIncrementString, false );
|
||||
|
@ -1504,13 +1506,14 @@ public abstract class AbstractEntityPersister
|
|||
getVersionType().nullSafeSet( st, nextVersion, 1, session );
|
||||
getIdentifierType().nullSafeSet( st, id, 2, session );
|
||||
getVersionType().nullSafeSet( st, currentVersion, 2 + getIdentifierColumnSpan(), session );
|
||||
int rows = session.getTransactionCoordinator().getJdbcCoordinator().getResultSetReturn().executeUpdate( st );
|
||||
int rows = session.getJdbcCoordinator().getResultSetReturn().executeUpdate( st );
|
||||
if ( rows != 1 ) {
|
||||
throw new StaleObjectStateException( getEntityName(), id );
|
||||
}
|
||||
}
|
||||
finally {
|
||||
session.getTransactionCoordinator().getJdbcCoordinator().release( st );
|
||||
session.getJdbcCoordinator().getResourceRegistry().release( st );
|
||||
session.getJdbcCoordinator().afterStatementExecution();
|
||||
}
|
||||
}
|
||||
catch ( SQLException sqle ) {
|
||||
|
@ -1547,13 +1550,13 @@ public abstract class AbstractEntityPersister
|
|||
}
|
||||
|
||||
try {
|
||||
PreparedStatement st = session.getTransactionCoordinator()
|
||||
PreparedStatement st = session
|
||||
.getJdbcCoordinator()
|
||||
.getStatementPreparer()
|
||||
.prepareStatement( getVersionSelectString() );
|
||||
try {
|
||||
getIdentifierType().nullSafeSet( st, id, 1, session );
|
||||
ResultSet rs = session.getTransactionCoordinator().getJdbcCoordinator().getResultSetReturn().extract( st );
|
||||
ResultSet rs = session.getJdbcCoordinator().getResultSetReturn().extract( st );
|
||||
try {
|
||||
if ( !rs.next() ) {
|
||||
return null;
|
||||
|
@ -1564,11 +1567,12 @@ public abstract class AbstractEntityPersister
|
|||
return getVersionType().nullSafeGet( rs, getVersionColumnName(), session, null );
|
||||
}
|
||||
finally {
|
||||
session.getTransactionCoordinator().getJdbcCoordinator().release( rs, st );
|
||||
session.getJdbcCoordinator().getResourceRegistry().release( rs, st );
|
||||
}
|
||||
}
|
||||
finally {
|
||||
session.getTransactionCoordinator().getJdbcCoordinator().release( st );
|
||||
session.getJdbcCoordinator().getResourceRegistry().release( st );
|
||||
session.getJdbcCoordinator().afterStatementExecution();
|
||||
}
|
||||
}
|
||||
catch ( SQLException e ) {
|
||||
|
@ -2514,12 +2518,12 @@ public abstract class AbstractEntityPersister
|
|||
final String sql = rootPersister.getSequentialSelect( getEntityName() );
|
||||
if ( sql != null ) {
|
||||
//TODO: I am not so sure about the exception handling in this bit!
|
||||
sequentialSelect = session.getTransactionCoordinator()
|
||||
sequentialSelect = session
|
||||
.getJdbcCoordinator()
|
||||
.getStatementPreparer()
|
||||
.prepareStatement( sql );
|
||||
rootPersister.getIdentifierType().nullSafeSet( sequentialSelect, id, 1, session );
|
||||
sequentialResultSet = session.getTransactionCoordinator().getJdbcCoordinator().getResultSetReturn().extract( sequentialSelect );
|
||||
sequentialResultSet = session.getJdbcCoordinator().getResultSetReturn().extract( sequentialSelect );
|
||||
if ( !sequentialResultSet.next() ) {
|
||||
// TODO: Deal with the "optional" attribute in the <join> mapping;
|
||||
// this code assumes that optional defaults to "true" because it
|
||||
|
@ -2576,7 +2580,7 @@ public abstract class AbstractEntityPersister
|
|||
}
|
||||
|
||||
if ( sequentialResultSet != null ) {
|
||||
session.getTransactionCoordinator().getJdbcCoordinator().release( sequentialResultSet, sequentialSelect );
|
||||
session.getJdbcCoordinator().getResourceRegistry().release( sequentialResultSet, sequentialSelect );
|
||||
}
|
||||
|
||||
return values;
|
||||
|
@ -2584,7 +2588,8 @@ public abstract class AbstractEntityPersister
|
|||
}
|
||||
finally {
|
||||
if ( sequentialSelect != null ) {
|
||||
session.getTransactionCoordinator().getJdbcCoordinator().release( sequentialSelect );
|
||||
session.getJdbcCoordinator().getResourceRegistry().release( sequentialSelect );
|
||||
session.getJdbcCoordinator().afterStatementExecution();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2700,13 +2705,13 @@ public abstract class AbstractEntityPersister
|
|||
// Render the SQL query
|
||||
final PreparedStatement insert;
|
||||
if ( useBatch ) {
|
||||
insert = session.getTransactionCoordinator()
|
||||
insert = session
|
||||
.getJdbcCoordinator()
|
||||
.getBatch( inserBatchKey )
|
||||
.getBatchStatement( sql, callable );
|
||||
}
|
||||
else {
|
||||
insert = session.getTransactionCoordinator()
|
||||
insert = session
|
||||
.getJdbcCoordinator()
|
||||
.getStatementPreparer()
|
||||
.prepareStatement( sql, callable );
|
||||
|
@ -2722,22 +2727,23 @@ public abstract class AbstractEntityPersister
|
|||
dehydrate( id, fields, null, notNull, propertyColumnInsertable, j, insert, session, index, false );
|
||||
|
||||
if ( useBatch ) {
|
||||
session.getTransactionCoordinator().getJdbcCoordinator().getBatch( inserBatchKey ).addToBatch();
|
||||
session.getJdbcCoordinator().getBatch( inserBatchKey ).addToBatch();
|
||||
}
|
||||
else {
|
||||
expectation.verifyOutcome( session.getTransactionCoordinator().getJdbcCoordinator().getResultSetReturn().executeUpdate( insert ), insert, -1 );
|
||||
expectation.verifyOutcome( session.getJdbcCoordinator().getResultSetReturn().executeUpdate( insert ), insert, -1 );
|
||||
}
|
||||
|
||||
}
|
||||
catch ( SQLException e ) {
|
||||
if ( useBatch ) {
|
||||
session.getTransactionCoordinator().getJdbcCoordinator().abortBatch();
|
||||
session.getJdbcCoordinator().abortBatch();
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
finally {
|
||||
if ( !useBatch ) {
|
||||
session.getTransactionCoordinator().getJdbcCoordinator().release( insert );
|
||||
session.getJdbcCoordinator().getResourceRegistry().release( insert );
|
||||
session.getJdbcCoordinator().afterStatementExecution();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2830,13 +2836,13 @@ public abstract class AbstractEntityPersister
|
|||
int index = 1; // starting index
|
||||
final PreparedStatement update;
|
||||
if ( useBatch ) {
|
||||
update = session.getTransactionCoordinator()
|
||||
update = session
|
||||
.getJdbcCoordinator()
|
||||
.getBatch( updateBatchKey )
|
||||
.getBatchStatement( sql, callable );
|
||||
}
|
||||
else {
|
||||
update = session.getTransactionCoordinator()
|
||||
update = session
|
||||
.getJdbcCoordinator()
|
||||
.getStatementPreparer()
|
||||
.prepareStatement( sql, callable );
|
||||
|
@ -2879,23 +2885,24 @@ public abstract class AbstractEntityPersister
|
|||
}
|
||||
|
||||
if ( useBatch ) {
|
||||
session.getTransactionCoordinator().getJdbcCoordinator().getBatch( updateBatchKey ).addToBatch();
|
||||
session.getJdbcCoordinator().getBatch( updateBatchKey ).addToBatch();
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return check( session.getTransactionCoordinator().getJdbcCoordinator().getResultSetReturn().executeUpdate( update ), id, j, expectation, update );
|
||||
return check( session.getJdbcCoordinator().getResultSetReturn().executeUpdate( update ), id, j, expectation, update );
|
||||
}
|
||||
|
||||
}
|
||||
catch ( SQLException e ) {
|
||||
if ( useBatch ) {
|
||||
session.getTransactionCoordinator().getJdbcCoordinator().abortBatch();
|
||||
session.getJdbcCoordinator().abortBatch();
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
finally {
|
||||
if ( !useBatch ) {
|
||||
session.getTransactionCoordinator().getJdbcCoordinator().release( update );
|
||||
session.getJdbcCoordinator().getResourceRegistry().release( update );
|
||||
session.getJdbcCoordinator().afterStatementExecution();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2957,13 +2964,13 @@ public abstract class AbstractEntityPersister
|
|||
PreparedStatement delete;
|
||||
int index = 1;
|
||||
if ( useBatch ) {
|
||||
delete = session.getTransactionCoordinator()
|
||||
delete = session
|
||||
.getJdbcCoordinator()
|
||||
.getBatch( deleteBatchKey )
|
||||
.getBatchStatement( sql, callable );
|
||||
}
|
||||
else {
|
||||
delete = session.getTransactionCoordinator()
|
||||
delete = session
|
||||
.getJdbcCoordinator()
|
||||
.getStatementPreparer()
|
||||
.prepareStatement( sql, callable );
|
||||
|
@ -2998,22 +3005,23 @@ public abstract class AbstractEntityPersister
|
|||
}
|
||||
|
||||
if ( useBatch ) {
|
||||
session.getTransactionCoordinator().getJdbcCoordinator().getBatch( deleteBatchKey ).addToBatch();
|
||||
session.getJdbcCoordinator().getBatch( deleteBatchKey ).addToBatch();
|
||||
}
|
||||
else {
|
||||
check( session.getTransactionCoordinator().getJdbcCoordinator().getResultSetReturn().executeUpdate( delete ), id, j, expectation, delete );
|
||||
check( session.getJdbcCoordinator().getResultSetReturn().executeUpdate( delete ), id, j, expectation, delete );
|
||||
}
|
||||
|
||||
}
|
||||
catch ( SQLException sqle ) {
|
||||
if ( useBatch ) {
|
||||
session.getTransactionCoordinator().getJdbcCoordinator().abortBatch();
|
||||
session.getJdbcCoordinator().abortBatch();
|
||||
}
|
||||
throw sqle;
|
||||
}
|
||||
finally {
|
||||
if ( !useBatch ) {
|
||||
session.getTransactionCoordinator().getJdbcCoordinator().release( delete );
|
||||
session.getJdbcCoordinator().getResourceRegistry().release( delete );
|
||||
session.getJdbcCoordinator().afterStatementExecution();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4432,16 +4440,16 @@ public abstract class AbstractEntityPersister
|
|||
String selectionSQL,
|
||||
GenerationTiming matchTiming) {
|
||||
// force immediate execution of the insert batch (if one)
|
||||
session.getTransactionCoordinator().getJdbcCoordinator().executeBatch();
|
||||
session.getJdbcCoordinator().executeBatch();
|
||||
|
||||
try {
|
||||
PreparedStatement ps = session.getTransactionCoordinator()
|
||||
PreparedStatement ps = session
|
||||
.getJdbcCoordinator()
|
||||
.getStatementPreparer()
|
||||
.prepareStatement( selectionSQL );
|
||||
try {
|
||||
getIdentifierType().nullSafeSet( ps, id, 1, session );
|
||||
ResultSet rs = session.getTransactionCoordinator().getJdbcCoordinator().getResultSetReturn().extract( ps );
|
||||
ResultSet rs = session.getJdbcCoordinator().getResultSetReturn().extract( ps );
|
||||
try {
|
||||
if ( !rs.next() ) {
|
||||
throw new HibernateException(
|
||||
|
@ -4474,12 +4482,13 @@ public abstract class AbstractEntityPersister
|
|||
}
|
||||
finally {
|
||||
if ( rs != null ) {
|
||||
session.getTransactionCoordinator().getJdbcCoordinator().release( rs, ps );
|
||||
session.getJdbcCoordinator().getResourceRegistry().release( rs, ps );
|
||||
}
|
||||
}
|
||||
}
|
||||
finally {
|
||||
session.getTransactionCoordinator().getJdbcCoordinator().release( ps );
|
||||
session.getJdbcCoordinator().getResourceRegistry().release( ps );
|
||||
session.getJdbcCoordinator().afterStatementExecution();
|
||||
}
|
||||
}
|
||||
catch( SQLException e ) {
|
||||
|
@ -4565,13 +4574,13 @@ public abstract class AbstractEntityPersister
|
|||
|
||||
Object[] snapshot = new Object[ naturalIdPropertyCount ];
|
||||
try {
|
||||
PreparedStatement ps = session.getTransactionCoordinator()
|
||||
PreparedStatement ps = session
|
||||
.getJdbcCoordinator()
|
||||
.getStatementPreparer()
|
||||
.prepareStatement( sql );
|
||||
try {
|
||||
getIdentifierType().nullSafeSet( ps, id, 1, session );
|
||||
ResultSet rs = session.getTransactionCoordinator().getJdbcCoordinator().getResultSetReturn().extract( ps );
|
||||
ResultSet rs = session.getJdbcCoordinator().getResultSetReturn().extract( ps );
|
||||
try {
|
||||
//if there is no resulting row, return null
|
||||
if ( !rs.next() ) {
|
||||
|
@ -4588,11 +4597,12 @@ public abstract class AbstractEntityPersister
|
|||
return snapshot;
|
||||
}
|
||||
finally {
|
||||
session.getTransactionCoordinator().getJdbcCoordinator().release( rs, ps );
|
||||
session.getJdbcCoordinator().getResourceRegistry().release( rs, ps );
|
||||
}
|
||||
}
|
||||
finally {
|
||||
session.getTransactionCoordinator().getJdbcCoordinator().release( ps );
|
||||
session.getJdbcCoordinator().getResourceRegistry().release( ps );
|
||||
session.getJdbcCoordinator().afterStatementExecution();
|
||||
}
|
||||
}
|
||||
catch ( SQLException e ) {
|
||||
|
@ -4621,7 +4631,7 @@ public abstract class AbstractEntityPersister
|
|||
final String sqlEntityIdByNaturalIdString = determinePkByNaturalIdQuery( valueNullness );
|
||||
|
||||
try {
|
||||
PreparedStatement ps = session.getTransactionCoordinator()
|
||||
PreparedStatement ps = session
|
||||
.getJdbcCoordinator()
|
||||
.getStatementPreparer()
|
||||
.prepareStatement( sqlEntityIdByNaturalIdString );
|
||||
|
@ -4636,7 +4646,7 @@ public abstract class AbstractEntityPersister
|
|||
positions += type.getColumnSpan( session.getFactory() );
|
||||
}
|
||||
}
|
||||
ResultSet rs = session.getTransactionCoordinator().getJdbcCoordinator().getResultSetReturn().extract( ps );
|
||||
ResultSet rs = session.getJdbcCoordinator().getResultSetReturn().extract( ps );
|
||||
try {
|
||||
// if there is no resulting row, return null
|
||||
if ( !rs.next() ) {
|
||||
|
@ -4647,11 +4657,12 @@ public abstract class AbstractEntityPersister
|
|||
return (Serializable) getIdentifierType().resolve( hydratedId, session, null );
|
||||
}
|
||||
finally {
|
||||
session.getTransactionCoordinator().getJdbcCoordinator().release( rs, ps );
|
||||
session.getJdbcCoordinator().getResourceRegistry().release( rs, ps );
|
||||
}
|
||||
}
|
||||
finally {
|
||||
session.getTransactionCoordinator().getJdbcCoordinator().release( ps );
|
||||
session.getJdbcCoordinator().getResourceRegistry().release( ps );
|
||||
session.getJdbcCoordinator().afterStatementExecution();
|
||||
}
|
||||
}
|
||||
catch ( SQLException e ) {
|
||||
|
|
|
@ -39,6 +39,7 @@ import org.hibernate.QueryException;
|
|||
import org.hibernate.cfg.NotYetImplementedException;
|
||||
import org.hibernate.engine.ResultSetMappingDefinition;
|
||||
import org.hibernate.engine.jdbc.env.spi.ExtractedDatabaseMetaData;
|
||||
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
|
||||
import org.hibernate.engine.query.spi.sql.NativeSQLQueryReturn;
|
||||
import org.hibernate.engine.spi.QueryParameters;
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
|
@ -311,11 +312,12 @@ public class ProcedureCallImpl extends AbstractBasicQueryContractImpl implements
|
|||
}
|
||||
if ( parameterStrategy == ParameterStrategy.UNKNOWN ) {
|
||||
// protect to only do this check once
|
||||
final ExtractedDatabaseMetaData databaseMetaData = getSession().getTransactionCoordinator()
|
||||
final ExtractedDatabaseMetaData databaseMetaData = getSession()
|
||||
.getJdbcCoordinator()
|
||||
.getLogicalConnection()
|
||||
.getJdbcServices()
|
||||
.getExtractedMetaDataSupport();
|
||||
.getJdbcSessionOwner()
|
||||
.getJdbcSessionContext()
|
||||
.getServiceRegistry().getService( JdbcEnvironment.class )
|
||||
.getExtractedDatabaseMetaData();
|
||||
if ( ! databaseMetaData.supportsNamedParameters() ) {
|
||||
LOG.unsupportedNamedParameters();
|
||||
}
|
||||
|
@ -404,7 +406,7 @@ public class ProcedureCallImpl extends AbstractBasicQueryContractImpl implements
|
|||
);
|
||||
|
||||
try {
|
||||
final CallableStatement statement = (CallableStatement) getSession().getTransactionCoordinator()
|
||||
final CallableStatement statement = (CallableStatement) getSession()
|
||||
.getJdbcCoordinator()
|
||||
.getStatementPreparer()
|
||||
.prepareStatement( call, true );
|
||||
|
|
|
@ -194,11 +194,8 @@ public abstract class AbstractLazyInitializer implements LazyInitializer {
|
|||
session.getPersistenceContext().setDefaultReadOnly( true );
|
||||
session.setFlushMode( FlushMode.MANUAL );
|
||||
|
||||
boolean isJTA = session.getTransactionCoordinator()
|
||||
.getTransactionContext().getTransactionEnvironment()
|
||||
.getTransactionFactory()
|
||||
.compatibleWithJtaSynchronization();
|
||||
|
||||
boolean isJTA = session.getTransactionCoordinator().getTransactionCoordinatorBuilder().isJta();
|
||||
|
||||
if ( !isJTA ) {
|
||||
// Explicitly handle the transactions only if we're not in
|
||||
// a JTA environment. A lazy loading temporary session can
|
||||
|
|
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2013, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.resource.jdbc;
|
||||
|
||||
import java.sql.Connection;
|
||||
|
||||
/**
|
||||
* Models the logical notion of a JDBC Connection. We may release/re-acquire physical JDBC connections under the
|
||||
* covers, but this logically represents the overall access to the JDBC Connection.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface LogicalConnection {
|
||||
/**
|
||||
* Is this (logical) JDBC Connection still open/active. In other words, has {@link #close} not been called yet?
|
||||
*
|
||||
* @return {@code true} if still open ({@link #close} has not been called yet); {@code false} if not open
|
||||
* (({@link #close} has been called).
|
||||
*/
|
||||
public boolean isOpen();
|
||||
|
||||
/**
|
||||
* Closes the JdbcSession, making it inactive and forcing release of any held resources
|
||||
*
|
||||
* @return Legacy :( Returns the JDBC Connection *if* the user passed in a Connection originally.
|
||||
*/
|
||||
public Connection close();
|
||||
|
||||
/**
|
||||
* Is this JdbcSession currently physically connected (meaning does it currently hold a JDBC Connection)?
|
||||
*
|
||||
* @return {@code true} if the JdbcSession currently hold a JDBC Connection; {@code false} if it does not.
|
||||
*/
|
||||
public boolean isPhysicallyConnected();
|
||||
|
||||
/**
|
||||
* Provides access to the registry of JDBC resources associated with this LogicalConnection.
|
||||
*
|
||||
* @return The JDBC resource registry.
|
||||
*
|
||||
* @throws org.hibernate.ResourceClosedException if the LogicalConnection is closed
|
||||
*/
|
||||
public ResourceRegistry getResourceRegistry();
|
||||
|
||||
}
|
|
@ -0,0 +1,94 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2013, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.resource.jdbc;
|
||||
|
||||
import java.sql.Blob;
|
||||
import java.sql.Clob;
|
||||
import java.sql.NClob;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.Statement;
|
||||
|
||||
/**
|
||||
* A registry for tracking JDBC resources
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface ResourceRegistry {
|
||||
/**
|
||||
* Does this registry currently have any registered resources?
|
||||
*
|
||||
* @return True if the registry does have registered resources; false otherwise.
|
||||
*/
|
||||
public boolean hasRegisteredResources();
|
||||
|
||||
public void releaseResources();
|
||||
|
||||
/**
|
||||
* Register a JDBC statement.
|
||||
*
|
||||
* @param statement The statement to register.
|
||||
* @param cancelable Is the statement being registered capable of being cancelled? In other words,
|
||||
* should we register it to be the target of subsequent {@link #cancelLastQuery()} calls?
|
||||
*/
|
||||
public void register(Statement statement, boolean cancelable);
|
||||
|
||||
/**
|
||||
* Release a previously registered statement.
|
||||
*
|
||||
* @param statement The statement to release.
|
||||
*/
|
||||
public void release(Statement statement);
|
||||
|
||||
/**
|
||||
* Register a JDBC result set.
|
||||
* <p/>
|
||||
* Implementation note: Second parameter has been introduced to prevent
|
||||
* multiple registrations of the same statement in case {@link java.sql.ResultSet#getStatement()}
|
||||
* does not return original {@link java.sql.Statement} object.
|
||||
*
|
||||
* @param resultSet The result set to register.
|
||||
* @param statement Statement from which {@link java.sql.ResultSet} has been generated.
|
||||
*/
|
||||
public void register(ResultSet resultSet, Statement statement);
|
||||
|
||||
/**
|
||||
* Release a previously registered result set.
|
||||
*
|
||||
* @param resultSet The result set to release.
|
||||
* @param statement Statement from which {@link java.sql.ResultSet} has been generated.
|
||||
*/
|
||||
public void release(ResultSet resultSet, Statement statement);
|
||||
|
||||
public void register(Blob blob);
|
||||
public void release(Blob blob);
|
||||
|
||||
public void register(Clob clob);
|
||||
public void release(Clob clob);
|
||||
|
||||
public void register(NClob nclob);
|
||||
public void release(NClob nclob);
|
||||
|
||||
public void cancelLastQuery();
|
||||
|
||||
}
|
|
@ -0,0 +1,134 @@
|
|||
package org.hibernate.resource.jdbc.internal;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
|
||||
import org.hibernate.ResourceClosedException;
|
||||
import org.hibernate.TransactionException;
|
||||
import org.hibernate.resource.jdbc.ResourceRegistry;
|
||||
import org.hibernate.resource.jdbc.spi.LogicalConnectionImplementor;
|
||||
import org.hibernate.resource.jdbc.spi.PhysicalJdbcTransaction;
|
||||
import org.hibernate.resource.transaction.spi.TransactionStatus;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public abstract class AbstractLogicalConnectionImplementor implements LogicalConnectionImplementor, PhysicalJdbcTransaction {
|
||||
private static final Logger log = Logger.getLogger( AbstractLogicalConnectionImplementor.class );
|
||||
|
||||
private TransactionStatus status = TransactionStatus.NOT_ACTIVE;
|
||||
protected ResourceRegistry resourceRegistry;
|
||||
|
||||
@Override
|
||||
public PhysicalJdbcTransaction getPhysicalJdbcTransaction() {
|
||||
errorIfClosed();
|
||||
return this;
|
||||
}
|
||||
|
||||
protected void errorIfClosed() {
|
||||
if ( !isOpen() ) {
|
||||
throw new ResourceClosedException( this.toString() + " is closed" );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceRegistry getResourceRegistry() {
|
||||
return resourceRegistry;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterStatement() {
|
||||
log.trace( "LogicalConnection#afterStatement" );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterTransaction() {
|
||||
log.trace( "LogicalConnection#afterTransaction" );
|
||||
|
||||
resourceRegistry.releaseResources();
|
||||
}
|
||||
|
||||
// PhysicalJdbcTransaction impl ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
protected abstract Connection getConnectionForTransactionManagement();
|
||||
|
||||
@Override
|
||||
public void begin() {
|
||||
try {
|
||||
log.trace( "Preparing to begin transaction via JDBC Connection.setAutoCommit(false)" );
|
||||
getConnectionForTransactionManagement().setAutoCommit( false );
|
||||
status = TransactionStatus.ACTIVE;
|
||||
log.trace( "Transaction begun via JDBC Connection.setAutoCommit(false)" );
|
||||
}
|
||||
catch( SQLException e ) {
|
||||
throw new TransactionException( "JDBC begin transaction failed: ", e );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void commit() {
|
||||
try {
|
||||
log.trace( "Preparing to commit transaction via JDBC Connection.commit()" );
|
||||
getConnectionForTransactionManagement().commit();
|
||||
status = TransactionStatus.COMMITTED;
|
||||
log.trace( "Transaction committed via JDBC Connection.commit()" );
|
||||
}
|
||||
catch( SQLException e ) {
|
||||
status = TransactionStatus.FAILED_COMMIT;
|
||||
throw new TransactionException( "Unable to commit against JDBC Connection", e );
|
||||
}
|
||||
|
||||
afterCompletion();
|
||||
}
|
||||
|
||||
protected void afterCompletion() {
|
||||
// by default, nothing to do
|
||||
}
|
||||
|
||||
protected void resetConnection(boolean initiallyAutoCommit) {
|
||||
try {
|
||||
if ( initiallyAutoCommit ) {
|
||||
log.trace( "re-enabling auto-commit on JDBC Connection after completion of JDBC-based transaction" );
|
||||
getConnectionForTransactionManagement().setAutoCommit( true );
|
||||
status = TransactionStatus.NOT_ACTIVE;
|
||||
}
|
||||
}
|
||||
catch ( Exception e ) {
|
||||
log.debug(
|
||||
"Could not re-enable auto-commit on JDBC Connection after completion of JDBC-based transaction : " + e
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rollback() {
|
||||
try {
|
||||
log.trace( "Preparing to rollback transaction via JDBC Connection.rollback()" );
|
||||
getConnectionForTransactionManagement().rollback();
|
||||
status = TransactionStatus.ROLLED_BACK;
|
||||
log.trace( "Transaction rolled-back via JDBC Connection.rollback()" );
|
||||
}
|
||||
catch( SQLException e ) {
|
||||
throw new TransactionException( "Unable to rollback against JDBC Connection", e );
|
||||
}
|
||||
|
||||
afterCompletion();
|
||||
}
|
||||
|
||||
protected static boolean determineInitialAutoCommitMode(Connection providedConnection) {
|
||||
try {
|
||||
return providedConnection.getAutoCommit();
|
||||
}
|
||||
catch (SQLException e) {
|
||||
log.debug( "Unable to ascertain initial auto-commit state of provided connection; assuming auto-commit" );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public TransactionStatus getStatus(){
|
||||
return status;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,241 @@
|
|||
package org.hibernate.resource.jdbc.internal;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
import org.hibernate.ConnectionReleaseMode;
|
||||
import org.hibernate.ResourceClosedException;
|
||||
import org.hibernate.engine.jdbc.connections.spi.JdbcConnectionAccess;
|
||||
import org.hibernate.engine.jdbc.spi.JdbcServices;
|
||||
import org.hibernate.engine.jdbc.spi.SqlExceptionHelper;
|
||||
import org.hibernate.resource.jdbc.ResourceRegistry;
|
||||
import org.hibernate.resource.jdbc.spi.JdbcObserver;
|
||||
import org.hibernate.resource.jdbc.spi.JdbcSessionContext;
|
||||
import org.hibernate.resource.jdbc.spi.LogicalConnectionImplementor;
|
||||
|
||||
/**
|
||||
* Represents a LogicalConnection where we manage obtaining and releasing the Connection as needed.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class LogicalConnectionManagedImpl extends AbstractLogicalConnectionImplementor {
|
||||
private static final Logger log = Logger.getLogger( LogicalConnectionManagedImpl.class );
|
||||
|
||||
private final transient JdbcConnectionAccess jdbcConnectionAccess;
|
||||
private final transient JdbcObserver observer;
|
||||
private final transient SqlExceptionHelper sqlExceptionHelper;
|
||||
private final transient ConnectionReleaseMode connectionReleaseMode;
|
||||
|
||||
private transient Connection physicalConnection;
|
||||
private boolean closed;
|
||||
|
||||
public LogicalConnectionManagedImpl(
|
||||
JdbcConnectionAccess jdbcConnectionAccess,
|
||||
JdbcSessionContext jdbcSessionContext) {
|
||||
this( jdbcConnectionAccess, jdbcSessionContext, new ResourceRegistryStandardImpl() );
|
||||
}
|
||||
|
||||
public LogicalConnectionManagedImpl(
|
||||
JdbcConnectionAccess jdbcConnectionAccess,
|
||||
JdbcSessionContext jdbcSessionContext,
|
||||
ResourceRegistry resourceRegistry) {
|
||||
this.jdbcConnectionAccess = jdbcConnectionAccess;
|
||||
this.observer = jdbcSessionContext.getObserver();
|
||||
|
||||
this.sqlExceptionHelper = jdbcSessionContext.getServiceRegistry()
|
||||
.getService( JdbcServices.class )
|
||||
.getSqlExceptionHelper();
|
||||
this.connectionReleaseMode = jdbcSessionContext.getConnectionReleaseMode();
|
||||
this.resourceRegistry = resourceRegistry;
|
||||
|
||||
if ( jdbcSessionContext.getConnectionAcquisitionMode() == JdbcSessionContext.ConnectionAcquisitionMode.IMMEDIATELY ) {
|
||||
if ( jdbcSessionContext.getConnectionReleaseMode() != ConnectionReleaseMode.ON_CLOSE ) {
|
||||
throw new IllegalStateException(
|
||||
"Illegal combination of ConnectionAcquisitionMode#IMMEDIATELY with !ConnectionReleaseMode.ON_CLOSE"
|
||||
);
|
||||
}
|
||||
acquireConnectionIfNeeded();
|
||||
}
|
||||
}
|
||||
|
||||
private LogicalConnectionManagedImpl(
|
||||
JdbcConnectionAccess jdbcConnectionAccess,
|
||||
JdbcSessionContext jdbcSessionContext,
|
||||
boolean closed) {
|
||||
this( jdbcConnectionAccess, jdbcSessionContext, new ResourceRegistryStandardImpl() );
|
||||
this.closed = closed;
|
||||
}
|
||||
|
||||
|
||||
private Connection acquireConnectionIfNeeded() {
|
||||
if ( physicalConnection == null ) {
|
||||
// todo : is this the right place for these observer calls?
|
||||
observer.jdbcConnectionAcquisitionStart();
|
||||
try {
|
||||
physicalConnection = jdbcConnectionAccess.obtainConnection();
|
||||
}
|
||||
catch (SQLException e) {
|
||||
throw sqlExceptionHelper.convert( e, "Unable to acquire JDBC Connection" );
|
||||
}
|
||||
finally {
|
||||
observer.jdbcConnectionAcquisitionEnd( physicalConnection );
|
||||
}
|
||||
}
|
||||
return physicalConnection;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOpen() {
|
||||
return !closed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPhysicallyConnected() {
|
||||
return physicalConnection != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Connection getPhysicalConnection() {
|
||||
errorIfClosed();
|
||||
return acquireConnectionIfNeeded();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterStatement() {
|
||||
super.afterStatement();
|
||||
|
||||
if ( connectionReleaseMode == 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 ( connectionReleaseMode != 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 Connection manualDisconnect() {
|
||||
if ( closed ) {
|
||||
throw new ResourceClosedException( "Logical connection is closed" );
|
||||
}
|
||||
final Connection c = physicalConnection;
|
||||
releaseConnection();
|
||||
return c;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void manualReconnect(Connection suppliedConnection) {
|
||||
if ( closed ) {
|
||||
throw new ResourceClosedException( "Logical connection is closed" );
|
||||
}
|
||||
|
||||
throw new IllegalStateException( "Cannot manually reconnect unless Connection was originally supplied by user" );
|
||||
}
|
||||
|
||||
private void releaseConnection() {
|
||||
if ( physicalConnection == null ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// todo : is this the right place for these observer calls?
|
||||
observer.jdbcConnectionReleaseStart();
|
||||
try {
|
||||
if ( !physicalConnection.isClosed() ) {
|
||||
sqlExceptionHelper.logAndClearWarnings( physicalConnection );
|
||||
}
|
||||
jdbcConnectionAccess.releaseConnection( physicalConnection );
|
||||
}
|
||||
catch (SQLException e) {
|
||||
throw sqlExceptionHelper.convert( e, "Unable to release JDBC Connection" );
|
||||
}
|
||||
finally {
|
||||
observer.jdbcConnectionReleaseEnd();
|
||||
physicalConnection = null;
|
||||
getResourceRegistry().releaseResources();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public LogicalConnectionImplementor makeShareableCopy() {
|
||||
errorIfClosed();
|
||||
|
||||
// todo : implement
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void serialize(ObjectOutputStream oos) throws IOException {
|
||||
oos.writeBoolean( closed );
|
||||
}
|
||||
|
||||
public static LogicalConnectionManagedImpl deserialize(
|
||||
ObjectInputStream ois,
|
||||
JdbcConnectionAccess jdbcConnectionAccess,
|
||||
JdbcSessionContext jdbcSessionContext) throws IOException, ClassNotFoundException {
|
||||
final boolean isClosed = ois.readBoolean();
|
||||
return new LogicalConnectionManagedImpl( jdbcConnectionAccess, jdbcSessionContext, isClosed );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Connection close() {
|
||||
if ( closed ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
getResourceRegistry().releaseResources();
|
||||
|
||||
log.trace( "Closing logical connection" );
|
||||
try {
|
||||
releaseConnection();
|
||||
}
|
||||
finally {
|
||||
// no matter what
|
||||
closed = true;
|
||||
log.trace( "Logical connection closed" );
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
// PhysicalJdbcTransaction impl ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
@Override
|
||||
protected Connection getConnectionForTransactionManagement() {
|
||||
return getPhysicalConnection();
|
||||
}
|
||||
|
||||
boolean initiallyAutoCommit;
|
||||
|
||||
@Override
|
||||
public void begin() {
|
||||
initiallyAutoCommit = determineInitialAutoCommitMode( getConnectionForTransactionManagement() );
|
||||
super.begin();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void afterCompletion() {
|
||||
afterTransaction();
|
||||
|
||||
resetConnection( initiallyAutoCommit );
|
||||
initiallyAutoCommit = false;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,164 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2013, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.resource.jdbc.internal;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.sql.Connection;
|
||||
|
||||
import org.hibernate.engine.jdbc.connections.spi.JdbcConnectionAccess;
|
||||
import org.hibernate.resource.jdbc.LogicalConnection;
|
||||
import org.hibernate.resource.jdbc.ResourceRegistry;
|
||||
import org.hibernate.resource.jdbc.spi.JdbcSessionContext;
|
||||
import org.hibernate.resource.jdbc.spi.LogicalConnectionImplementor;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class LogicalConnectionProvidedImpl extends AbstractLogicalConnectionImplementor {
|
||||
private static final Logger log = Logger.getLogger( LogicalConnection.class );
|
||||
|
||||
private transient Connection providedConnection;
|
||||
private final boolean initiallyAutoCommit;
|
||||
private boolean closed;
|
||||
|
||||
public LogicalConnectionProvidedImpl(Connection providedConnection) {
|
||||
this( providedConnection, new ResourceRegistryStandardImpl() );
|
||||
}
|
||||
|
||||
public LogicalConnectionProvidedImpl(Connection providedConnection, ResourceRegistry resourceRegistry) {
|
||||
this.resourceRegistry = resourceRegistry;
|
||||
if ( providedConnection == null ) {
|
||||
throw new IllegalArgumentException( "Provided Connection cannot be null" );
|
||||
}
|
||||
|
||||
this.providedConnection = providedConnection;
|
||||
this.initiallyAutoCommit = determineInitialAutoCommitMode( providedConnection );
|
||||
}
|
||||
|
||||
private LogicalConnectionProvidedImpl(boolean closed, boolean initiallyAutoCommit) {
|
||||
this.resourceRegistry = new ResourceRegistryStandardImpl();
|
||||
this.closed = closed;
|
||||
this.initiallyAutoCommit = initiallyAutoCommit;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOpen() {
|
||||
return !closed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Connection close() {
|
||||
log.trace( "Closing logical connection" );
|
||||
|
||||
getResourceRegistry().releaseResources();
|
||||
|
||||
try {
|
||||
return providedConnection;
|
||||
}
|
||||
finally {
|
||||
providedConnection = null;
|
||||
closed = true;
|
||||
log.trace( "Logical connection closed" );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPhysicallyConnected() {
|
||||
return providedConnection != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Connection getPhysicalConnection() {
|
||||
errorIfClosed();
|
||||
return providedConnection;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LogicalConnectionImplementor makeShareableCopy() {
|
||||
errorIfClosed();
|
||||
|
||||
return new LogicalConnectionProvidedImpl( providedConnection );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void serialize(ObjectOutputStream oos) throws IOException {
|
||||
oos.writeBoolean( closed );
|
||||
oos.writeBoolean( initiallyAutoCommit );
|
||||
}
|
||||
|
||||
public static LogicalConnectionProvidedImpl deserialize(
|
||||
ObjectInputStream ois) throws IOException, ClassNotFoundException {
|
||||
final boolean isClosed = ois.readBoolean();
|
||||
final boolean initiallyAutoCommit = ois.readBoolean();
|
||||
return new LogicalConnectionProvidedImpl( isClosed, initiallyAutoCommit );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Connection manualDisconnect() {
|
||||
errorIfClosed();
|
||||
try {
|
||||
resourceRegistry.releaseResources();
|
||||
return providedConnection;
|
||||
}
|
||||
finally {
|
||||
this.providedConnection = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void manualReconnect(Connection connection) {
|
||||
errorIfClosed();
|
||||
|
||||
if ( connection == null ) {
|
||||
throw new IllegalArgumentException( "cannot reconnect using a null connection" );
|
||||
}
|
||||
else if ( connection == providedConnection ) {
|
||||
// likely an unmatched reconnect call (no matching disconnect call)
|
||||
log.debug( "reconnecting the same connection that is already connected; should this connection have been disconnected?" );
|
||||
}
|
||||
else if ( providedConnection != null ) {
|
||||
throw new IllegalArgumentException(
|
||||
"cannot reconnect to a new user-supplied connection because currently connected; must disconnect before reconnecting."
|
||||
);
|
||||
}
|
||||
providedConnection = connection;
|
||||
log.debug( "Manually reconnected logical connection" );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Connection getConnectionForTransactionManagement() {
|
||||
return providedConnection;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void afterCompletion() {
|
||||
afterTransaction();
|
||||
|
||||
resetConnection( initiallyAutoCommit );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,337 @@
|
|||
package org.hibernate.resource.jdbc.internal;
|
||||
|
||||
import java.sql.Blob;
|
||||
import java.sql.Clob;
|
||||
import java.sql.NClob;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Statement;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.JDBCException;
|
||||
import org.hibernate.internal.CoreLogging;
|
||||
import org.hibernate.internal.CoreMessageLogger;
|
||||
import org.hibernate.resource.jdbc.ResourceRegistry;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class ResourceRegistryStandardImpl implements ResourceRegistry {
|
||||
private static final CoreMessageLogger log = CoreLogging.messageLogger( ResourceRegistryStandardImpl.class );
|
||||
|
||||
private final Map<Statement, Set<ResultSet>> xref = new HashMap<Statement, Set<ResultSet>>();
|
||||
private final Set<ResultSet> unassociatedResultSets = new HashSet<ResultSet>();
|
||||
|
||||
private List<Blob> blobs;
|
||||
private List<Clob> clobs;
|
||||
private List<NClob> nclobs;
|
||||
|
||||
private Statement lastQuery;
|
||||
|
||||
@Override
|
||||
public boolean hasRegisteredResources() {
|
||||
return hasRegistered( xref )
|
||||
|| hasRegistered( unassociatedResultSets )
|
||||
|| hasRegistered( blobs )
|
||||
|| hasRegistered( clobs )
|
||||
|| hasRegistered( nclobs );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void register(Statement statement, boolean cancelable) {
|
||||
log.tracef( "Registering statement [%s]", statement );
|
||||
if ( xref.containsKey( statement ) ) {
|
||||
throw new HibernateException( "JDBC Statement already registered" );
|
||||
}
|
||||
xref.put( statement, null );
|
||||
|
||||
if ( cancelable ) {
|
||||
lastQuery = statement;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void release(Statement statement) {
|
||||
log.tracev( "Releasing statement [{0}]", statement );
|
||||
|
||||
// Keep this at DEBUG level, rather than warn. Numerous connection pool implementations can return a
|
||||
// proxy/wrapper around the JDBC Statement, causing excessive logging here. See HHH-8210.
|
||||
if ( log.isDebugEnabled() && !xref.containsKey( statement ) ) {
|
||||
log.unregisteredStatement();
|
||||
}
|
||||
else {
|
||||
final Set<ResultSet> resultSets = xref.get( statement );
|
||||
if ( resultSets != null ) {
|
||||
closeAll( resultSets );
|
||||
}
|
||||
xref.remove( statement );
|
||||
}
|
||||
close( statement );
|
||||
|
||||
if ( lastQuery == statement ) {
|
||||
lastQuery = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void release(ResultSet resultSet, Statement statement) {
|
||||
log.tracef( "Releasing result set [%s]", resultSet );
|
||||
|
||||
if ( statement == null ) {
|
||||
try {
|
||||
statement = resultSet.getStatement();
|
||||
}
|
||||
catch (SQLException e) {
|
||||
throw convert( e, "unable to access Statement from ResultSet" );
|
||||
}
|
||||
}
|
||||
if ( statement != null ) {
|
||||
final Set<ResultSet> resultSets = xref.get( statement );
|
||||
if ( resultSets == null ) {
|
||||
log.unregisteredStatement();
|
||||
}
|
||||
else {
|
||||
resultSets.remove( resultSet );
|
||||
if ( resultSets.isEmpty() ) {
|
||||
xref.remove( statement );
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
final boolean removed = unassociatedResultSets.remove( resultSet );
|
||||
if ( !removed ) {
|
||||
log.unregisteredResultSetWithoutStatement();
|
||||
}
|
||||
|
||||
}
|
||||
close( resultSet );
|
||||
}
|
||||
|
||||
protected void closeAll(Set<ResultSet> resultSets) {
|
||||
for ( ResultSet resultSet : resultSets ) {
|
||||
close( resultSet );
|
||||
}
|
||||
resultSets.clear();
|
||||
}
|
||||
|
||||
@SuppressWarnings({"unchecked"})
|
||||
public static void close(ResultSet resultSet) {
|
||||
log.tracef( "Closing result set [%s]", resultSet );
|
||||
|
||||
try {
|
||||
resultSet.close();
|
||||
}
|
||||
catch (SQLException e) {
|
||||
log.debugf( "Unable to release JDBC result set [%s]", e.getMessage() );
|
||||
}
|
||||
catch (Exception e) {
|
||||
// try to handle general errors more elegantly
|
||||
log.debugf( "Unable to release JDBC result set [%s]", e.getMessage() );
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings({"unchecked"})
|
||||
public static void close(Statement statement) {
|
||||
log.tracef( "Closing prepared statement [%s]", statement );
|
||||
|
||||
try {
|
||||
// if we are unable to "clean" the prepared statement,
|
||||
// we do not close it
|
||||
try {
|
||||
if ( statement.getMaxRows() != 0 ) {
|
||||
statement.setMaxRows( 0 );
|
||||
}
|
||||
if ( statement.getQueryTimeout() != 0 ) {
|
||||
statement.setQueryTimeout( 0 );
|
||||
}
|
||||
}
|
||||
catch (SQLException sqle) {
|
||||
// there was a problem "cleaning" the prepared statement
|
||||
if ( log.isDebugEnabled() ) {
|
||||
log.debugf( "Exception clearing maxRows/queryTimeout [%s]", sqle.getMessage() );
|
||||
}
|
||||
// EARLY EXIT!!!
|
||||
return;
|
||||
}
|
||||
statement.close();
|
||||
}
|
||||
catch (SQLException e) {
|
||||
log.debugf( "Unable to release JDBC statement [%s]", e.getMessage() );
|
||||
}
|
||||
catch (Exception e) {
|
||||
// try to handle general errors more elegantly
|
||||
log.debugf( "Unable to release JDBC statement [%s]", e.getMessage() );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void register(ResultSet resultSet, Statement statement) {
|
||||
log.tracef( "Registering result set [%s]", resultSet );
|
||||
|
||||
if ( statement == null ) {
|
||||
try {
|
||||
statement = resultSet.getStatement();
|
||||
}
|
||||
catch (SQLException e) {
|
||||
throw convert( e, "unable to access Statement from ResultSet" );
|
||||
}
|
||||
}
|
||||
if ( statement != null ) {
|
||||
// Keep this at DEBUG level, rather than warn. Numerous connection pool implementations can return a
|
||||
// proxy/wrapper around the JDBC Statement, causing excessive logging here. See HHH-8210.
|
||||
if ( log.isDebugEnabled() && !xref.containsKey( statement ) ) {
|
||||
log.debug( "ResultSet statement was not registered (on register)" );
|
||||
}
|
||||
Set<ResultSet> resultSets = xref.get( statement );
|
||||
if ( resultSets == null ) {
|
||||
resultSets = new HashSet<ResultSet>();
|
||||
xref.put( statement, resultSets );
|
||||
}
|
||||
resultSets.add( resultSet );
|
||||
}
|
||||
else {
|
||||
unassociatedResultSets.add( resultSet );
|
||||
}
|
||||
}
|
||||
|
||||
private JDBCException convert(SQLException e, String s) {
|
||||
// todo : implement
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void register(Blob blob) {
|
||||
if ( blobs == null ) {
|
||||
blobs = new ArrayList<Blob>();
|
||||
}
|
||||
|
||||
blobs.add( blob );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void release(Blob blob) {
|
||||
if ( blobs == null ) {
|
||||
log.debug( "Request to release Blob, but appears no Blobs have ever been registered" );
|
||||
return;
|
||||
}
|
||||
blobs.remove( blob );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void register(Clob clob) {
|
||||
if ( clobs == null ) {
|
||||
clobs = new ArrayList<Clob>();
|
||||
}
|
||||
clobs.add( clob );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void release(Clob clob) {
|
||||
if ( clobs == null ) {
|
||||
log.debug( "Request to release Clob, but appears no Clobs have ever been registered" );
|
||||
return;
|
||||
}
|
||||
clobs.remove( clob );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void register(NClob nclob) {
|
||||
// todo : just store them in clobs?
|
||||
if ( nclobs == null ) {
|
||||
nclobs = new ArrayList<NClob>();
|
||||
}
|
||||
nclobs.add( nclob );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void release(NClob nclob) {
|
||||
// todo : just store them in clobs?
|
||||
if ( nclobs == null ) {
|
||||
log.debug( "Request to release NClob, but appears no NClobs have ever been registered" );
|
||||
return;
|
||||
}
|
||||
nclobs.remove( nclob );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancelLastQuery() {
|
||||
try {
|
||||
if ( lastQuery != null ) {
|
||||
lastQuery.cancel();
|
||||
}
|
||||
}
|
||||
catch (SQLException e) {
|
||||
throw convert( e, "Cannot cancel query" );
|
||||
}
|
||||
finally {
|
||||
lastQuery = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void releaseResources() {
|
||||
log.trace( "Releasing JDBC resources" );
|
||||
|
||||
for ( Map.Entry<Statement, Set<ResultSet>> entry : xref.entrySet() ) {
|
||||
if ( entry.getValue() != null ) {
|
||||
closeAll( entry.getValue() );
|
||||
}
|
||||
close( entry.getKey() );
|
||||
}
|
||||
xref.clear();
|
||||
|
||||
closeAll( unassociatedResultSets );
|
||||
|
||||
if ( blobs != null ) {
|
||||
for ( Blob blob : blobs ) {
|
||||
try {
|
||||
blob.free();
|
||||
}
|
||||
catch (SQLException e) {
|
||||
log.debugf( "Unable to free JDBC Blob reference [%s]", e.getMessage() );
|
||||
}
|
||||
}
|
||||
blobs.clear();
|
||||
}
|
||||
|
||||
if ( clobs != null ) {
|
||||
for ( Clob clob : clobs ) {
|
||||
try {
|
||||
clob.free();
|
||||
}
|
||||
catch (SQLException e) {
|
||||
log.debugf( "Unable to free JDBC Clob reference [%s]", e.getMessage() );
|
||||
}
|
||||
}
|
||||
clobs.clear();
|
||||
}
|
||||
|
||||
if ( nclobs != null ) {
|
||||
for ( NClob nclob : nclobs ) {
|
||||
try {
|
||||
nclob.free();
|
||||
}
|
||||
catch (SQLException e) {
|
||||
log.debugf( "Unable to free JDBC NClob reference [%s]", e.getMessage() );
|
||||
}
|
||||
}
|
||||
nclobs.clear();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private boolean hasRegistered(Map resource) {
|
||||
return resource != null && !resource.isEmpty();
|
||||
}
|
||||
|
||||
private boolean hasRegistered(Collection resource) {
|
||||
return resource != null && !resource.isEmpty();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2013, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.resource.jdbc.spi;
|
||||
|
||||
import java.sql.Connection;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface JdbcObserver {
|
||||
public void jdbcConnectionAcquisitionStart();
|
||||
public void jdbcConnectionAcquisitionEnd(Connection connection);
|
||||
|
||||
public void jdbcConnectionReleaseStart();
|
||||
public void jdbcConnectionReleaseEnd();
|
||||
|
||||
public void jdbcPrepareStatementStart();
|
||||
public void jdbcPrepareStatementEnd();
|
||||
|
||||
public void jdbcExecuteStatementStart();
|
||||
public void jdbcExecuteStatementEnd();
|
||||
|
||||
public void jdbcExecuteBatchStart();
|
||||
public void jdbcExecuteBatchEnd();
|
||||
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2011, Red Hat Inc. or third-party contributors as
|
||||
* Copyright (c) 2013, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
|
@ -21,51 +21,44 @@
|
|||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.engine.transaction.spi;
|
||||
package org.hibernate.resource.jdbc.spi;
|
||||
|
||||
import org.hibernate.ConnectionReleaseMode;
|
||||
import org.hibernate.engine.jdbc.spi.JdbcServices;
|
||||
import org.hibernate.engine.jdbc.spi.SqlExceptionHelper;
|
||||
import org.hibernate.engine.jdbc.spi.SqlStatementLogger;
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.engine.transaction.jta.platform.spi.JtaPlatform;
|
||||
import org.hibernate.stat.spi.StatisticsImplementor;
|
||||
import org.hibernate.service.ServiceRegistry;
|
||||
|
||||
/**
|
||||
* Provides access to transactional services.
|
||||
* Provides the JdbcSession implementation with contextual information it needs during its lifecycle.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface TransactionEnvironment {
|
||||
public interface JdbcSessionContext {
|
||||
public boolean isScrollableResultSetsEnabled();
|
||||
public boolean isGetGeneratedKeysEnabled();
|
||||
public int getFetchSize();
|
||||
|
||||
public ConnectionReleaseMode getConnectionReleaseMode();
|
||||
public ConnectionAcquisitionMode getConnectionAcquisitionMode();
|
||||
|
||||
public StatementInspector getStatementInspector();
|
||||
|
||||
public JdbcObserver getObserver();
|
||||
|
||||
/**
|
||||
* Retrieve the session factory for this environment.
|
||||
*
|
||||
* @return The session factory
|
||||
*/
|
||||
* Retrieve the session factory for this environment.
|
||||
*
|
||||
* @return The session factory
|
||||
*/
|
||||
public SessionFactoryImplementor getSessionFactory();
|
||||
|
||||
/**
|
||||
* Retrieve the JDBC services for this environment.
|
||||
*
|
||||
* @return The JDBC services
|
||||
*/
|
||||
public JdbcServices getJdbcServices();
|
||||
public ServiceRegistry getServiceRegistry();
|
||||
|
||||
/**
|
||||
* Retrieve the JTA platform for this environment.
|
||||
*
|
||||
* @return The JTA platform
|
||||
*/
|
||||
public JtaPlatform getJtaPlatform();
|
||||
|
||||
/**
|
||||
* Retrieve the transaction factory for this environment.
|
||||
*
|
||||
* @return The transaction factory
|
||||
*/
|
||||
public TransactionFactory getTransactionFactory();
|
||||
|
||||
/**
|
||||
* Get access to the statistics collector
|
||||
*
|
||||
* @return The statistics collector
|
||||
*/
|
||||
public StatisticsImplementor getStatisticsImplementor();
|
||||
public static enum ConnectionAcquisitionMode {
|
||||
IMMEDIATELY,
|
||||
AS_NEEDED,
|
||||
DEFAULT
|
||||
}
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2013, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.resource.jdbc.spi;
|
||||
|
||||
import org.hibernate.engine.jdbc.connections.spi.JdbcConnectionAccess;
|
||||
import org.hibernate.resource.transaction.TransactionCoordinatorBuilder;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface JdbcSessionOwner {
|
||||
/**
|
||||
* Obtain the builder for TransactionCoordinator instances
|
||||
*
|
||||
* @return The TransactionCoordinatorBuilder
|
||||
*/
|
||||
public TransactionCoordinatorBuilder getTransactionCoordinatorBuilder();
|
||||
|
||||
public JdbcSessionContext getJdbcSessionContext();
|
||||
|
||||
public JdbcConnectionAccess getJdbcConnectionAccess();
|
||||
|
||||
/**
|
||||
* A after-begin callback from the coordinator to its owner.
|
||||
*/
|
||||
public void afterTransactionBegin();
|
||||
|
||||
/**
|
||||
* A before-completion callback to the owner.
|
||||
*/
|
||||
public void beforeTransactionCompletion();
|
||||
|
||||
/**
|
||||
* An after-completion callback to the owner.
|
||||
*
|
||||
* @param successful Was the transaction successful?
|
||||
*/
|
||||
public void afterTransactionCompletion(boolean successful);
|
||||
|
||||
public void flushBeforeTransactionCompletion();
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2010, Red Hat Inc. or third-party contributors as
|
||||
* Copyright (c) 2013, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
|
@ -21,52 +21,39 @@
|
|||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.engine.jdbc.spi;
|
||||
package org.hibernate.resource.jdbc.spi;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.sql.Connection;
|
||||
|
||||
import org.hibernate.ConnectionReleaseMode;
|
||||
import org.hibernate.JDBCException;
|
||||
import org.hibernate.engine.jdbc.spi.ConnectionObserver;
|
||||
import org.hibernate.resource.jdbc.LogicalConnection;
|
||||
|
||||
/**
|
||||
* The "internal" contract for LogicalConnection
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
* @author Brett Meyer
|
||||
*/
|
||||
public interface LogicalConnectionImplementor extends LogicalConnection {
|
||||
/**
|
||||
* Obtains the JDBC services associated with this logical connection.
|
||||
*
|
||||
* @return JDBC services
|
||||
*/
|
||||
public JdbcServices getJdbcServices();
|
||||
// todo : expose the Connection as below? or accept(WorkInConnection) where WorkInConnection is given access to Connection?
|
||||
public Connection getPhysicalConnection();
|
||||
|
||||
/**
|
||||
* Add an observer interested in notification of connection events.
|
||||
*
|
||||
* @param observer The observer.
|
||||
* Notification indicating a JDBC statement has been executed to trigger
|
||||
* {@link org.hibernate.ConnectionReleaseMode#AFTER_STATEMENT} releasing if needed
|
||||
*/
|
||||
public void addObserver(ConnectionObserver observer);
|
||||
public void afterStatement();
|
||||
|
||||
/**
|
||||
* Remove an observer
|
||||
*
|
||||
* @param connectionObserver The observer to remove.
|
||||
* Notification indicating a transaction has completed to trigger
|
||||
* {@link org.hibernate.ConnectionReleaseMode#AFTER_TRANSACTION} releasing if needed
|
||||
*/
|
||||
public void removeObserver(ConnectionObserver connectionObserver);
|
||||
|
||||
/**
|
||||
* The release mode under which this logical connection is operating.
|
||||
*
|
||||
* @return the release mode.
|
||||
*/
|
||||
public ConnectionReleaseMode getConnectionReleaseMode();
|
||||
public void afterTransaction();
|
||||
|
||||
/**
|
||||
* Manually disconnect the underlying JDBC Connection. The assumption here
|
||||
* is that the manager will be reconnected at a later point in time.
|
||||
*
|
||||
* @return The connection maintained here at time of disconnect. Null if
|
||||
* @return The connection maintained here at time of disconnect. {@code null} if
|
||||
* there was no connection cached internally.
|
||||
*/
|
||||
public Connection manualDisconnect();
|
||||
|
@ -80,33 +67,20 @@ public interface LogicalConnectionImplementor extends LogicalConnection {
|
|||
public void manualReconnect(Connection suppliedConnection);
|
||||
|
||||
/**
|
||||
* Perform an aggressive release
|
||||
*/
|
||||
public void aggressiveRelease();
|
||||
|
||||
/**
|
||||
* Release any held connection.
|
||||
* Creates a shareable copy of itself for use in "shared sessions"
|
||||
*
|
||||
* @throws JDBCException Indicates a problem releasing the connection
|
||||
* @return The shareable copy.
|
||||
*/
|
||||
public void releaseConnection() throws JDBCException;
|
||||
public LogicalConnectionImplementor makeShareableCopy();
|
||||
|
||||
public PhysicalJdbcTransaction getPhysicalJdbcTransaction();
|
||||
|
||||
/**
|
||||
* Is this logical connection in auto-commit mode?
|
||||
* Serialization hook
|
||||
*
|
||||
* @return {@code true} if auto-commit
|
||||
*/
|
||||
public boolean isAutoCommit();
|
||||
|
||||
/**
|
||||
* Callback to notify all registered observers of a connection being prepared.
|
||||
*/
|
||||
public void notifyObserversStatementPrepared();
|
||||
|
||||
/**
|
||||
* Does this logical connection wrap a user/application supplied connection?
|
||||
* @param oos The stream to write out state to
|
||||
*
|
||||
* @return {@code true} if the underlying connection was user supplied.
|
||||
* @throws java.io.IOException Problem accessing stream
|
||||
*/
|
||||
public boolean isUserSuppliedConnection();
|
||||
public void serialize(ObjectOutputStream oos) throws IOException;
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2013, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.resource.jdbc.spi;
|
||||
|
||||
import org.hibernate.resource.transaction.backend.store.spi.DataStoreTransaction;
|
||||
|
||||
/**
|
||||
* Provides access to manage "transactionality" via the JDBC Connection
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface PhysicalJdbcTransaction extends DataStoreTransaction {
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2011, Red Hat Inc. or third-party contributors as
|
||||
* Copyright (c) 2013, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
|
@ -21,27 +21,21 @@
|
|||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.engine.transaction.synchronization.spi;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.hibernate.engine.transaction.spi.TransactionCoordinator;
|
||||
package org.hibernate.resource.jdbc.spi;
|
||||
|
||||
/**
|
||||
* A pluggable strategy for defining how the {@link javax.transaction.Synchronization} registered by Hibernate determines
|
||||
* whether to perform a managed flush. An exceptions from either this delegate or the subsequent flush are routed
|
||||
* through the sister strategy {@link ExceptionMapper}.
|
||||
* Contract to allow inspection (and swapping) of SQL to be prepared
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface ManagedFlushChecker extends Serializable {
|
||||
public interface StatementInspector {
|
||||
/**
|
||||
* Check whether we should perform the managed flush
|
||||
* Inspect the given SQL, possibly returning a different SQL to be used instead. Note that returning {@code null}
|
||||
* is interpreted as returning the same SQL as was passed.
|
||||
*
|
||||
* @param coordinator The transaction coordinator
|
||||
* @param jtaStatus The status of the current JTA transaction.
|
||||
* @param sql The SQL to inspect
|
||||
*
|
||||
* @return True to indicate to perform the managed flush; false otherwise.
|
||||
* @return The SQL to use; may be {@code null}
|
||||
*/
|
||||
public boolean shouldDoManagedFlush(TransactionCoordinator coordinator, int jtaStatus);
|
||||
public String inspect(String sql);
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2013, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.resource.transaction;
|
||||
|
||||
import org.hibernate.HibernateException;
|
||||
|
||||
/**
|
||||
* Wraps an exception thrown from a "local synchronization" (one registered in the SynchronizationRegistry).
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class LocalSynchronizationException extends HibernateException {
|
||||
public LocalSynchronizationException(String message, Throwable cause) {
|
||||
super( message, cause );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2010, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.resource.transaction;
|
||||
|
||||
import org.hibernate.HibernateException;
|
||||
|
||||
/**
|
||||
* Indicates an attempt to register a null synchronization. Basically a glorified {@link NullPointerException}
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class NullSynchronizationException extends HibernateException {
|
||||
public NullSynchronizationException() {
|
||||
this( "Synchronization to register cannot be null" );
|
||||
}
|
||||
|
||||
public NullSynchronizationException(String s) {
|
||||
super( s );
|
||||
}
|
||||
}
|
|
@ -21,18 +21,23 @@
|
|||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.engine.transaction.synchronization.spi;
|
||||
package org.hibernate.resource.transaction;
|
||||
|
||||
|
||||
import org.hibernate.engine.transaction.spi.TransactionCoordinator;
|
||||
import java.io.Serializable;
|
||||
import javax.transaction.Synchronization;
|
||||
|
||||
/**
|
||||
* A pluggable strategy for defining any actions to be performed during
|
||||
* {@link javax.transaction.Synchronization#afterCompletion} processing from the the
|
||||
* {@link javax.transaction.Synchronization} registered by Hibernate with the underlying JTA platform.
|
||||
* Manages a registry of (local) JTA {@link Synchronization} instances
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface AfterCompletionAction {
|
||||
public void doAction(TransactionCoordinator transactionCoordinator, int status);
|
||||
public interface SynchronizationRegistry extends Serializable {
|
||||
/**
|
||||
* Register a {@link Synchronization} callback for this transaction.
|
||||
*
|
||||
* @param synchronization The synchronization callback to register.
|
||||
*
|
||||
* @throws NullSynchronizationException if the synchronization is {@code null}
|
||||
*/
|
||||
void registerSynchronization(Synchronization synchronization);
|
||||
}
|
|
@ -0,0 +1,150 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2013, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.resource.transaction;
|
||||
|
||||
import org.hibernate.engine.transaction.spi.IsolationDelegate;
|
||||
import org.hibernate.engine.transaction.spi.TransactionObserver;
|
||||
import org.hibernate.resource.transaction.spi.TransactionStatus;
|
||||
|
||||
/**
|
||||
* Models the coordination of all transaction related flows.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface TransactionCoordinator {
|
||||
/**
|
||||
* Indicates an explicit request to join a transaction. This is mainly intended to handle the JPA requirement
|
||||
* around {@link javax.persistence.EntityManager#joinTransaction()}, and generally speaking only has an impact in
|
||||
* JTA environments
|
||||
*/
|
||||
public void explicitJoin();
|
||||
|
||||
/**
|
||||
* Determine if there is an active transaction that this coordinator is already joined to.
|
||||
*
|
||||
* @return {@code true} if there is an active transaction this coordinator is already joined to; {@code false}
|
||||
* otherwise.
|
||||
*/
|
||||
public boolean isJoined();
|
||||
|
||||
/**
|
||||
* Used by owner of the JdbcSession as a means to indicate that implicit joining should be done if needed.
|
||||
*/
|
||||
public void pulse();
|
||||
|
||||
/**
|
||||
* Get the delegate used by the local transaction driver to control the underlying transaction
|
||||
*
|
||||
* @return The control delegate.
|
||||
*/
|
||||
public LocalInflow getTransactionDriverControl();
|
||||
|
||||
/**
|
||||
* Get access to the local registry of Synchronization instances
|
||||
*
|
||||
* @return The local Synchronization registry
|
||||
*/
|
||||
public SynchronizationRegistry getLocalSynchronizations();
|
||||
|
||||
/**
|
||||
* 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
|
||||
* transaction is active when it is initiated directly through the JDBC {@link java.sql.Connection}, only when
|
||||
* it is initiated from here.
|
||||
*
|
||||
* @return {@code true} if the transaction is still active; {@code false} otherwise.
|
||||
*
|
||||
* @throws org.hibernate.HibernateException Indicates a problem checking the transaction status.
|
||||
*/
|
||||
public boolean isActive();
|
||||
|
||||
/**
|
||||
* Retrieve an isolation delegate appropriate for this transaction strategy.
|
||||
*
|
||||
* @return An isolation delegate.
|
||||
*/
|
||||
public IsolationDelegate createIsolationDelegate();
|
||||
|
||||
/**
|
||||
* Adds an observer to the coordinator.
|
||||
* <p/>
|
||||
* observers are not to be cleared on transaction completion.
|
||||
*
|
||||
* @param observer The observer to add.
|
||||
*/
|
||||
public void addObserver(TransactionObserver observer);
|
||||
|
||||
/**
|
||||
* Removed an observer from the coordinator.
|
||||
*
|
||||
* @param observer The observer to remove.
|
||||
*/
|
||||
public void removeObserver(TransactionObserver observer);
|
||||
|
||||
/**
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public TransactionCoordinatorBuilder getTransactionCoordinatorBuilder();
|
||||
|
||||
public void setTimeOut(int seconds);
|
||||
|
||||
public int getTimeOut();
|
||||
|
||||
/**
|
||||
* Provides the means for "local transactions" (as transaction drivers) to control the
|
||||
* underlying "physical transaction" currently associated with the TransactionCoordinator.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface LocalInflow {
|
||||
/**
|
||||
* Begin the physical transaction
|
||||
*/
|
||||
public void begin();
|
||||
|
||||
/**
|
||||
* Commit the physical transaction
|
||||
*/
|
||||
public void commit();
|
||||
|
||||
/**
|
||||
* Rollback the physical transaction
|
||||
*/
|
||||
public void rollback();
|
||||
|
||||
public TransactionStatus getStatus();
|
||||
|
||||
public void markRollbackOnly();
|
||||
|
||||
// todo : org.hibernate.Transaction will need access to register local Synchronizations.
|
||||
// depending on how we integrate TransactionCoordinator/TransactionDriverControl with
|
||||
// org.hibernate.Transaction that might be best done by:
|
||||
// 1) exposing registerSynchronization here (if the Transaction is just passed this)
|
||||
// 2) using the exposed TransactionCoordinator#getLocalSynchronizations (if the Transaction is passed the TransactionCoordinator)
|
||||
//
|
||||
// if
|
||||
}
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2013, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.resource.transaction;
|
||||
|
||||
import org.hibernate.ConnectionReleaseMode;
|
||||
import org.hibernate.resource.jdbc.spi.JdbcSessionContext;
|
||||
import org.hibernate.resource.transaction.TransactionCoordinator;
|
||||
import org.hibernate.resource.transaction.spi.TransactionCoordinatorOwner;
|
||||
import org.hibernate.service.Service;
|
||||
|
||||
import static org.hibernate.resource.jdbc.spi.JdbcSessionContext.ConnectionAcquisitionMode;
|
||||
|
||||
/**
|
||||
* Builder for TransactionCoordinator instances
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface TransactionCoordinatorBuilder extends Service {
|
||||
public TransactionCoordinator buildTransactionCoordinator(TransactionCoordinatorOwner owner);
|
||||
|
||||
public boolean isJta();
|
||||
|
||||
public ConnectionReleaseMode getDefaultConnectionReleaseMode();
|
||||
|
||||
public ConnectionAcquisitionMode getDefaultConnectionAcquisitionMode();
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2013, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.resource.transaction;
|
||||
|
||||
import org.hibernate.resource.transaction.backend.jta.internal.JtaTransactionCoordinatorBuilderImpl;
|
||||
import org.hibernate.resource.transaction.backend.store.internal.ResourceLocalTransactionCoordinatorBuilderImpl;
|
||||
|
||||
/**
|
||||
* Factory for obtaining instances of standard TransactionCoordinatorBuilder implementations
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class TransactionCoordinatorBuilderFactory {
|
||||
/**
|
||||
* Singleton access
|
||||
*/
|
||||
public static final TransactionCoordinatorBuilderFactory INSTANCE = new TransactionCoordinatorBuilderFactory();
|
||||
|
||||
/**
|
||||
* Private constructor for the factory
|
||||
*/
|
||||
private TransactionCoordinatorBuilderFactory() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtain a TransactionCoordinatorBuilder specific to resource-local environments
|
||||
*
|
||||
* @return The resource-local specific TransactionCoordinatorBuilder
|
||||
*/
|
||||
public TransactionCoordinatorResourceLocalBuilder forResourceLocal() {
|
||||
return new ResourceLocalTransactionCoordinatorBuilderImpl();
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtain a TransactionCoordinatorBuilder specific to JTA environments
|
||||
*
|
||||
* @return The JTA specific TransactionCoordinatorBuilder
|
||||
*/
|
||||
public TransactionCoordinatorJtaBuilder forJta() {
|
||||
return new JtaTransactionCoordinatorBuilderImpl();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2013, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.resource.transaction;
|
||||
|
||||
import org.hibernate.engine.transaction.jta.platform.spi.JtaPlatform;
|
||||
|
||||
/**
|
||||
* A builder of TransactionCoordinator instances intended for use in JTA environments.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface TransactionCoordinatorJtaBuilder extends TransactionCoordinatorBuilder {
|
||||
/**
|
||||
* Specifies the JtaPlatform to use.
|
||||
*
|
||||
* @param jtaPlatform The JtaPlatform to use.
|
||||
*
|
||||
* @return {@code this}, for method chaining
|
||||
*/
|
||||
public TransactionCoordinatorJtaBuilder setJtaPlatform(JtaPlatform jtaPlatform);
|
||||
|
||||
/**
|
||||
* Should JTA transactions be automatically joined? Or should we wait for (JPA-style) explicit joining? The
|
||||
* default is to auto-join ({@code true}).
|
||||
*
|
||||
* @param autoJoinTransactions {@code true} (default) indicates that JTA transactions should be auto joined;
|
||||
* {@code false} indicated we should wait for an explicit join
|
||||
*
|
||||
* @return {@code this}, for method chaining
|
||||
*/
|
||||
public TransactionCoordinatorJtaBuilder setAutoJoinTransactions(boolean autoJoinTransactions);
|
||||
|
||||
/**
|
||||
* Should we prefer to use UserTransactions (over TransactionManager) for managing transactions (mainly for calling
|
||||
* begin, commit, rollback)? We will try both, this controls which to check first. The default is to prefer
|
||||
* accessing the TransactionManager
|
||||
*
|
||||
* @param preferUserTransactions {@code true} indicates to look for UserTransactions first; {@code false} (the
|
||||
* default) indicates to looks for the TransactionManager first,
|
||||
*
|
||||
* @return {@code this}, for method chaining
|
||||
*/
|
||||
public TransactionCoordinatorJtaBuilder setPreferUserTransactions(boolean preferUserTransactions);
|
||||
|
||||
/**
|
||||
* Should we track threads in order to protect against the JTA system calling us from a different thread? This
|
||||
* might often be the case for JTA systems which implement timeout rollbacks from separate "reaper" threads. The
|
||||
* default is to track threads.
|
||||
*
|
||||
* @param performJtaThreadTracking {@code true} (the default) indicates that the thread should be tracked;
|
||||
* {@code false} indicates it should not.
|
||||
*
|
||||
* @return {@code this}, for method chaining
|
||||
*/
|
||||
public TransactionCoordinatorJtaBuilder setPerformJtaThreadTracking(boolean performJtaThreadTracking);
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2013, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.resource.transaction;
|
||||
|
||||
import org.hibernate.resource.transaction.backend.store.spi.DataStoreTransactionAccess;
|
||||
|
||||
/**
|
||||
* A builder of TransactionCoordinator instances intended for use in resource-local mode (non-JTA transactions local
|
||||
* to the underlying data store).
|
||||
* <p/>
|
||||
* NOTE : Ideally I'd love to specialize the {@link #buildTransactionCoordinator(org.hibernate.resource.transaction.spi.TransactionCoordinatorOwner)}
|
||||
* method here to only accept TransactionCoordinatorOwner arguments that are specifically
|
||||
* {@link org.hibernate.resource.transaction.backend.store.spi.DataStoreTransactionAccess} instances. Not sure how to
|
||||
* best achieve that. For now we just cast and let the exception happen, but directing the user via the contract
|
||||
* would be MUCH preferable.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface TransactionCoordinatorResourceLocalBuilder extends TransactionCoordinatorBuilder {
|
||||
/**
|
||||
* Provides the TransactionCoordinator we are building with access to the ResourceLocalTransaction used to control
|
||||
* transactions.
|
||||
* <p/>
|
||||
* An alternative is for the owner passed to {@link #buildTransactionCoordinator} to implement the
|
||||
* ResourceLocalTransactionAccess contract.
|
||||
*
|
||||
* @param dataStoreTransactionAccess Access
|
||||
*/
|
||||
public void setResourceLocalTransactionAccess(DataStoreTransactionAccess dataStoreTransactionAccess);
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2011, Red Hat Inc. or third-party contributors as
|
||||
* Copyright (c) {DATE}, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
|
@ -21,20 +21,19 @@
|
|||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.engine.transaction.internal.jta;
|
||||
package org.hibernate.resource.transaction.backend.jta.internal;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
import javax.transaction.NotSupportedException;
|
||||
import javax.transaction.SystemException;
|
||||
import javax.transaction.Transaction;
|
||||
import javax.transaction.TransactionManager;
|
||||
import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.engine.jdbc.connections.spi.JdbcConnectionAccess;
|
||||
import org.hibernate.engine.jdbc.spi.SqlExceptionHelper;
|
||||
import org.hibernate.engine.transaction.spi.IsolationDelegate;
|
||||
import org.hibernate.engine.transaction.spi.TransactionCoordinator;
|
||||
import org.hibernate.internal.CoreLogging;
|
||||
import org.hibernate.internal.CoreMessageLogger;
|
||||
import org.hibernate.jdbc.WorkExecutor;
|
||||
|
@ -43,39 +42,34 @@ import org.hibernate.jdbc.WorkExecutorVisitable;
|
|||
/**
|
||||
* An isolation delegate for JTA environments.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
* @author Andrea Boriero
|
||||
*/
|
||||
public class JtaIsolationDelegate implements IsolationDelegate {
|
||||
private static final CoreMessageLogger LOG = CoreLogging.messageLogger( JtaIsolationDelegate.class );
|
||||
|
||||
private final TransactionCoordinator transactionCoordinator;
|
||||
private final JdbcConnectionAccess connectionAccess;
|
||||
private final SqlExceptionHelper sqlExceptionHelper;
|
||||
private final TransactionManager transactionManager;
|
||||
|
||||
public JtaIsolationDelegate(TransactionCoordinator transactionCoordinator) {
|
||||
this.transactionCoordinator = transactionCoordinator;
|
||||
}
|
||||
|
||||
protected TransactionManager transactionManager() {
|
||||
return transactionCoordinator.getTransactionContext()
|
||||
.getTransactionEnvironment()
|
||||
.getJtaPlatform()
|
||||
.retrieveTransactionManager();
|
||||
public JtaIsolationDelegate(
|
||||
JdbcConnectionAccess connectionAccess,
|
||||
SqlExceptionHelper sqlExceptionHelper,
|
||||
TransactionManager transactionManager) {
|
||||
this.connectionAccess = connectionAccess;
|
||||
this.sqlExceptionHelper = sqlExceptionHelper;
|
||||
this.transactionManager = transactionManager;
|
||||
}
|
||||
|
||||
protected JdbcConnectionAccess jdbcConnectionAccess() {
|
||||
return transactionCoordinator.getTransactionContext().getJdbcConnectionAccess();
|
||||
return this.connectionAccess;
|
||||
}
|
||||
|
||||
protected SqlExceptionHelper sqlExceptionHelper() {
|
||||
return transactionCoordinator.getTransactionContext()
|
||||
.getTransactionEnvironment()
|
||||
.getJdbcServices()
|
||||
.getSqlExceptionHelper();
|
||||
return this.sqlExceptionHelper;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T delegateWork(WorkExecutorVisitable<T> work, boolean transacted) throws HibernateException {
|
||||
TransactionManager transactionManager = transactionManager();
|
||||
|
||||
try {
|
||||
// First we suspend any current JTA transaction
|
||||
Transaction surroundingTransaction = transactionManager.suspend();
|
||||
|
@ -91,7 +85,7 @@ public class JtaIsolationDelegate implements IsolationDelegate {
|
|||
return doTheWorkInNoTransaction( work );
|
||||
}
|
||||
}
|
||||
catch ( HibernateException e ) {
|
||||
catch (HibernateException e) {
|
||||
hadProblems = true;
|
||||
throw e;
|
||||
}
|
||||
|
@ -100,7 +94,7 @@ public class JtaIsolationDelegate implements IsolationDelegate {
|
|||
transactionManager.resume( surroundingTransaction );
|
||||
LOG.debugf( "Surrounding JTA transaction resumed [%s]", surroundingTransaction );
|
||||
}
|
||||
catch( Throwable t ) {
|
||||
catch (Throwable t) {
|
||||
// if the actually work had an error use that, otherwise error based on t
|
||||
if ( !hadProblems ) {
|
||||
//noinspection ThrowFromFinallyBlock
|
||||
|
@ -109,7 +103,7 @@ public class JtaIsolationDelegate implements IsolationDelegate {
|
|||
}
|
||||
}
|
||||
}
|
||||
catch ( SystemException e ) {
|
||||
catch (SystemException e) {
|
||||
throw new HibernateException( "Unable to suspend current JTA transaction", e );
|
||||
}
|
||||
}
|
||||
|
@ -125,20 +119,20 @@ public class JtaIsolationDelegate implements IsolationDelegate {
|
|||
transactionManager.commit();
|
||||
return result;
|
||||
}
|
||||
catch ( Exception e ) {
|
||||
catch (Exception e) {
|
||||
try {
|
||||
transactionManager.rollback();
|
||||
}
|
||||
catch ( Exception ignore ) {
|
||||
catch (Exception ignore) {
|
||||
LOG.unableToRollbackIsolatedTransaction( e, ignore );
|
||||
}
|
||||
throw new HibernateException( "Could not apply work", e );
|
||||
}
|
||||
}
|
||||
catch ( SystemException e ) {
|
||||
catch (SystemException e) {
|
||||
throw new HibernateException( "Unable to start isolated transaction", e );
|
||||
}
|
||||
catch ( NotSupportedException e ) {
|
||||
catch (NotSupportedException e) {
|
||||
throw new HibernateException( "Unable to start isolated transaction", e );
|
||||
}
|
||||
}
|
||||
|
@ -155,10 +149,10 @@ public class JtaIsolationDelegate implements IsolationDelegate {
|
|||
// do the actual work
|
||||
return work.accept( new WorkExecutor<T>(), 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 {
|
||||
|
@ -166,14 +160,13 @@ public class JtaIsolationDelegate implements IsolationDelegate {
|
|||
// no matter what, release the connection (handle)
|
||||
jdbcConnectionAccess().releaseConnection( connection );
|
||||
}
|
||||
catch ( Throwable ignore ) {
|
||||
catch (Throwable ignore) {
|
||||
LOG.unableToReleaseIsolatedConnection( ignore );
|
||||
}
|
||||
}
|
||||
}
|
||||
catch ( SQLException e ) {
|
||||
catch (SQLException e) {
|
||||
throw sqlExceptionHelper().convert( e, "unable to obtain isolated JDBC connection" );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2014, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.resource.transaction.backend.jta.internal;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
import org.jboss.logging.annotations.MessageLogger;
|
||||
import org.jboss.logging.annotations.ValidIdRange;
|
||||
|
||||
/**
|
||||
* Acts as the {@link org.jboss.logging.annotations.MessageLogger} related to
|
||||
* JTA transaction processing
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
@MessageLogger( projectCode = "HHH" )
|
||||
@ValidIdRange( min = 10001001, max = 10002000 )
|
||||
public interface JtaMessageLogger {
|
||||
public static final JtaMessageLogger INSTANCE = Logger.getMessageLogger(
|
||||
JtaMessageLogger.class,
|
||||
"org.hibernate.orm.txn.backend.jta"
|
||||
);
|
||||
|
||||
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue