@Override protected Object doGetTransaction() { JpaTransactionObject txObject = new JpaTransactionObject(); txObject.setSavepointAllowed(isNestedTransactionAllowed()); EntityManagerHolder emHolder = (EntityManagerHolder) TransactionSynchronizationManager.getResource(getEntityManagerFactory()); if (emHolder != null) { if (logger.isDebugEnabled()) { logger.debug( "Found thread-bound EntityManager [" + emHolder.getEntityManager() + "] for JPA transaction"); } txObject.setEntityManagerHolder(emHolder, false); } if (getDataSource() != null) { ConnectionHolder conHolder = (ConnectionHolder) TransactionSynchronizationManager.getResource(getDataSource()); txObject.setConnectionHolder(conHolder); } return txObject; }
public void testLoggingAutoActivate() throws Throwable { assertFalse( "Auto-logging of misuse of the wrapper should be off", BorrowedConnectionProxy.isCallStackTraced()); UserTransaction txn = transactionService.getUserTransaction(); Connection connection; try { txn.begin(); // Dig the proxy out of ... somewhere ConnectionHolder conHolder = (ConnectionHolder) TransactionSynchronizationManager.getResource(dataSource); connection = conHolder.getConnection(); txn.commit(); } catch (Throwable e) { try { txn.rollback(); } catch (Throwable ee) { } throw e; } // Now mess with the connection, which is protected by the Hibernate wrapper try { connection.commit(); fail("Use case should have generated a HibernateException"); } catch (HibernateException e) { // Expected } assertTrue( "Auto-logging of misuse of the wrapper should now be on", BorrowedConnectionProxy.isCallStackTraced()); // Now start a new transaction and we should see logging txn = transactionService.getUserTransaction(); try { txn.begin(); // Dig the proxy out of ... somewhere ConnectionHolder conHolder = (ConnectionHolder) TransactionSynchronizationManager.getResource(dataSource); connection = conHolder.getConnection(); txn.commit(); } catch (Throwable e) { try { txn.rollback(); } catch (Throwable ee) { } throw e; } // Now mess with the connection, which is protected by the Hibernate wrapper try { connection.commit(); fail("Use case should have generated a HibernateException"); } catch (HibernateException e) { // Expected } // Check for error logs }
/** Retrieve the Spring-managed Session for the current thread, if any. */ public Session currentSession() throws HibernateException { Object value = TransactionSynchronizationManager.getResource(this.sessionFactory); if (value instanceof Session) { return (Session) value; } else if (value instanceof SessionHolder) { SessionHolder sessionHolder = (SessionHolder) value; Session session = sessionHolder.getSession(); if (TransactionSynchronizationManager.isSynchronizationActive() && !sessionHolder.isSynchronizedWithTransaction()) { TransactionSynchronizationManager.registerSynchronization( new SpringSessionSynchronization(sessionHolder, this.sessionFactory)); sessionHolder.setSynchronizedWithTransaction(true); // Switch to FlushMode.AUTO, as we have to assume a thread-bound Session // with FlushMode.MANUAL, which needs to allow flushing within the transaction. FlushMode flushMode = session.getFlushMode(); if (FlushMode.isManualFlushMode(flushMode) && !TransactionSynchronizationManager.isCurrentTransactionReadOnly()) { session.setFlushMode(FlushMode.AUTO); sessionHolder.setPreviousFlushMode(flushMode); } } return session; } else if (this.jtaSessionContext != null) { Session session = this.jtaSessionContext.currentSession(); if (TransactionSynchronizationManager.isSynchronizationActive()) { TransactionSynchronizationManager.registerSynchronization( new SpringFlushSynchronization(session)); } return session; } else { throw new HibernateException("No Session found for current thread"); } }
/** * Get a TopLink Session for the given SessionFactory. Is aware of and will return any existing * corresponding Session bound to the current thread, for example when using * TopLinkTransactionManager. Will create a new Session otherwise, if allowCreate is true. * * <p>Same as <code>getSession</code>, but throwing the original TopLinkException. * * @param sessionFactory TopLink SessionFactory to create the session with * @param allowCreate if a non-transactional Session should be created when no transactional * Session can be found for the current thread * @return the TopLink Session * @throws TopLinkException if the Session couldn't be created * @throws IllegalStateException if no thread-bound Session found and allowCreate false * @see #releaseSession * @see TopLinkTemplate */ public static Session doGetSession(SessionFactory sessionFactory, boolean allowCreate) throws TopLinkException, IllegalStateException { Assert.notNull(sessionFactory, "No SessionFactory specified"); SessionHolder sessionHolder = (SessionHolder) TransactionSynchronizationManager.getResource(sessionFactory); if (sessionHolder != null) { return sessionHolder.getSession(); } if (!allowCreate && !TransactionSynchronizationManager.isSynchronizationActive()) { throw new IllegalStateException( "No TopLink Session bound to thread, " + "and configuration does not allow creation of non-transactional one here"); } logger.debug("Creating TopLink Session"); Session session = sessionFactory.createSession(); if (TransactionSynchronizationManager.isSynchronizationActive()) { logger.debug("Registering new Spring transaction synchronization for new TopLink Session"); // Use same Session for further TopLink actions within the transaction. // Thread object will get removed by synchronization at transaction completion. sessionHolder = new SessionHolder(session); sessionHolder.setSynchronizedWithTransaction(true); TransactionSynchronizationManager.registerSynchronization( new SessionSynchronization(sessionHolder, sessionFactory)); TransactionSynchronizationManager.bindResource(sessionFactory, sessionHolder); } return session; }
@Override protected Object doGetTransaction() { EntityManagerHolder holder = (EntityManagerHolder) TransactionSynchronizationManager.getResource(getEntityManagerFactory()); boolean isNew = false; if (holder == null) { EntityManager em = _jpaContext.getEm(getEntityManagerFactory()); holder = new EntityManagerHolder(em); TransactionSynchronizationManager.bindResource(getEntityManagerFactory(), holder); isNew = true; } JdbcTransactionObjectSupport transactionObj = (JdbcTransactionObjectSupport) super.doGetTransaction(); if (isNew) { _newTransactionObjects.put(transactionObj, holder.getEntityManager()); LOGGER.debug( "doGetTransaction() bound EntityManagerHolder [{}] and saved transactionObj [{}]", holder, transactionObj); } else { LOGGER.debug( "doGetTransaction() existing EntityManagerHolder, ignoring transactionObj: {}", holder, transactionObj); } return transactionObj; }
/** * Determine whether the given JDBC Connection is transactional, that is, bound to the current * thread by Spring's transaction facilities. * * @param con the Connection to check * @param dataSource the DataSource that the Connection was obtained from (may be <code>null * </code>) * @return whether the Connection is transactional */ public static boolean isConnectionTransactional(Connection con, DataSource dataSource) { if (dataSource == null) { return false; } ConnectionHolder conHolder = (ConnectionHolder) TransactionSynchronizationManager.getResource(dataSource); return (conHolder != null && connectionEquals(conHolder, con)); }
/** * Return whether the given TopLink Session is transactional, that is, bound to the current thread * by Spring's transaction facilities. * * @param session the TopLink Session to check * @param sessionFactory TopLink SessionFactory that the Session was created with (can be <code> * null</code>) * @return whether the Session is transactional */ public static boolean isSessionTransactional(Session session, SessionFactory sessionFactory) { if (sessionFactory == null) { return false; } SessionHolder sessionHolder = (SessionHolder) TransactionSynchronizationManager.getResource(sessionFactory); return (sessionHolder != null && session == sessionHolder.getSession()); }
/** * Determine whether the given JMS Session is transactional, that is, bound to the current thread * by Spring's transaction facilities. * * @param session the JMS Session to check * @param cf the JMS ConnectionFactory that the Session originated from * @return whether the Session is transactional */ public static boolean isSessionTransactional(Session session, ConnectionFactory cf) { if (session == null || cf == null) { return false; } JmsResourceHolder resourceHolder = (JmsResourceHolder) TransactionSynchronizationManager.getResource(cf); return (resourceHolder != null && resourceHolder.containsSession(session)); }
public static List<String> bindAndGetEventLog(EventLogSender eventLogSender) { if (!TransactionSynchronizationManager.hasResource(EVENT_LOG_KEY)) { TransactionSynchronizationManager.bindResource(EVENT_LOG_KEY, new ArrayList<String>()); TransactionSynchronizationManager.registerSynchronization( new EventLogSynchronization(eventLogSender)); } return (List<String>) TransactionSynchronizationManager.getResource(EVENT_LOG_KEY); }
/** * Return whether the given DB instance is transactional, that is, bound to the current thread by * Spring's transaction facilities. * * @param db the DB to check * @param mongo the Mongo instance that the DB was created with (may be <code>null</code>) * @return whether the DB is transactional */ public static boolean isDBTransactional(DB db, Mongo mongo) { if (mongo == null) { return false; } DbHolder dbHolder = (DbHolder) TransactionSynchronizationManager.getResource(mongo); return dbHolder != null && dbHolder.containsDB(db); }
/** * Apply the current transaction timeout, if any, to the given JPA Query object. * * <p>This method sets the JPA 2.0 query hints "javax.persistence.lock.timeout" and * "javax.persistence.query.timeout" accordingly. * * @param query the JPA Query object * @param emf JPA EntityManagerFactory that the Query was created for */ public static void applyTransactionTimeout(Query query, EntityManagerFactory emf) { EntityManagerHolder emHolder = (EntityManagerHolder) TransactionSynchronizationManager.getResource(emf); if (emHolder != null && emHolder.hasTimeout()) { int timeoutValue = emHolder.getTimeToLiveInSeconds(); query.setHint("javax.persistence.lock.timeout", timeoutValue); query.setHint("javax.persistence.query.timeout", timeoutValue); } }
public Connection getConnection(DataSource dataSource) { ConnectionHolder connectionHolder = (ConnectionHolder) TransactionSynchronizationManager.getResource(dataSource); if (connectionHolder == null) { return null; } else { return connectionHolder.getConnection(); } }
/** * Return whether the given Redis connection is transactional, that is, bound to the current * thread by Spring's transaction facilities. * * @param conn Redis connection to check * @param connFactory Redis connection factory that the connection was created with * @return whether the connection is transactional or not */ public static boolean isConnectionTransactional( RedisConnection conn, RedisConnectionFactory connFactory) { if (connFactory == null) { return false; } RedisConnectionHolder connHolder = (RedisConnectionHolder) TransactionSynchronizationManager.getResource(connFactory); return (connHolder != null && conn == connHolder.getConnection()); }
private void endSession(PhaseEvent event) { if (event.getPhaseId().equals(PhaseId.RENDER_RESPONSE)) { final SessionHolder sessionHolder = (SessionHolder) TransactionSynchronizationManager.getResource(sessionFactory); if (sessionHolder != null && !FlushMode.MANUAL.equals(sessionHolder.getSession().getFlushMode())) { sessionHolder.getSession().flush(); } if (boundByMe.get()) unbindSession(); } }
/** * Apply the current transaction timeout, if any, to the given JPA Query object. * * <p>This method sets the JPA 2.0 query hint "javax.persistence.query.timeout" accordingly. * * @param query the JPA Query object * @param emf JPA EntityManagerFactory that the Query was created for */ public static void applyTransactionTimeout(Query query, EntityManagerFactory emf) { EntityManagerHolder emHolder = (EntityManagerHolder) TransactionSynchronizationManager.getResource(emf); if (emHolder != null && emHolder.hasTimeout()) { int timeoutValue = (int) emHolder.getTimeToLiveInMillis(); try { query.setHint("javax.persistence.query.timeout", timeoutValue); } catch (IllegalArgumentException ex) { // oh well, at least we tried... } } }
@Override protected Session getSession() { SessionHolder sessionHolder = (SessionHolder) TransactionSynchronizationManager.getResource(jpaDatastore); if (sessionHolder == null) { Session session = jpaDatastore.connect(); sessionHolder = new SessionHolder(session); TransactionSynchronizationManager.bindResource(jpaDatastore, sessionHolder); return session; } return sessionHolder.getSession(); }
/** * Obtain a JPA EntityManager from the given factory. Is aware of a corresponding EntityManager * bound to the current thread, for example when using JpaTransactionManager. * * <p>Same as <code>getEntityManager</code>, but throwing the original PersistenceException. * * @param emf EntityManagerFactory to create the EntityManager with * @param properties the properties to be passed into the <code>createEntityManager</code> call * (may be <code>null</code>) * @return the EntityManager, or <code>null</code> if none found * @throws javax.persistence.PersistenceException if the EntityManager couldn't be created * @see #getTransactionalEntityManager(javax.persistence.EntityManagerFactory) * @see JpaTransactionManager */ public static EntityManager doGetTransactionalEntityManager( EntityManagerFactory emf, Map properties) throws PersistenceException { Assert.notNull(emf, "No EntityManagerFactory specified"); EntityManagerHolder emHolder = (EntityManagerHolder) TransactionSynchronizationManager.getResource(emf); if (emHolder != null) { if (!emHolder.isSynchronizedWithTransaction() && TransactionSynchronizationManager.isSynchronizationActive()) { // Try to explicitly synchronize the EntityManager itself // with an ongoing JTA transaction, if any. try { emHolder.getEntityManager().joinTransaction(); } catch (TransactionRequiredException ex) { logger.debug("Could not join JTA transaction because none was active", ex); } Object transactionData = prepareTransaction(emHolder.getEntityManager(), emf); TransactionSynchronizationManager.registerSynchronization( new EntityManagerSynchronization(emHolder, emf, transactionData, false)); emHolder.setSynchronizedWithTransaction(true); } return emHolder.getEntityManager(); } if (!TransactionSynchronizationManager.isSynchronizationActive()) { // Indicate that we can't obtain a transactional EntityManager. return null; } // Create a new EntityManager for use within the current transaction. logger.debug("Opening JPA EntityManager"); EntityManager em = (!CollectionUtils.isEmpty(properties) ? emf.createEntityManager(properties) : emf.createEntityManager()); if (TransactionSynchronizationManager.isSynchronizationActive()) { logger.debug("Registering transaction synchronization for JPA EntityManager"); // Use same EntityManager for further JPA actions within the transaction. // Thread object will get removed by synchronization at transaction completion. emHolder = new EntityManagerHolder(em); Object transactionData = prepareTransaction(em, emf); TransactionSynchronizationManager.registerSynchronization( new EntityManagerSynchronization(emHolder, emf, transactionData, true)); emHolder.setSynchronizedWithTransaction(true); TransactionSynchronizationManager.bindResource(emf, emHolder); } return em; }
/** * Apply the specified timeout - overridden by the current transaction timeout, if any - to the * given JDBC Statement object. * * @param stmt the JDBC Statement object * @param dataSource the DataSource that the Connection was obtained from * @param timeout the timeout to apply (or 0 for no timeout outside of a transaction) * @throws SQLException if thrown by JDBC methods * @see java.sql.Statement#setQueryTimeout */ public static void applyTimeout(Statement stmt, DataSource dataSource, int timeout) throws SQLException { Assert.notNull(stmt, "No Statement specified"); Assert.notNull(dataSource, "No DataSource specified"); ConnectionHolder holder = (ConnectionHolder) TransactionSynchronizationManager.getResource(dataSource); if (holder != null && holder.hasTimeout()) { // Remaining transaction timeout overrides specified value. stmt.setQueryTimeout(holder.getTimeToLiveInSeconds()); } else if (timeout > 0) { // No current transaction timeout -> apply specified value. stmt.setQueryTimeout(timeout); } }
private boolean bindSession() { if (sessionFactory == null) { throw new IllegalStateException("No sessionFactory property provided"); } final Object inStorage = TransactionSynchronizationManager.getResource(sessionFactory); if (inStorage != null) { ((SessionHolder) inStorage).getSession().flush(); return false; } else { Session session = SessionFactoryUtils.getSession(sessionFactory, true); session.setFlushMode(FlushMode.AUTO); TransactionSynchronizationManager.bindResource(sessionFactory, new SessionHolder(session)); return true; } }
/** * Gets a Redis connection. Is aware of and will return any existing corresponding connections * bound to the current thread, for example when using a transaction manager. Will create a new * Connection otherwise, if {@code allowCreate} is <tt>true</tt>. * * @param factory connection factory for creating the connection * @param allowCreate whether a new (unbound) connection should be created when no connection can * be found for the current thread * @param bind binds the connection to the thread, in case one was created * @param enableTransactionSupport * @return an active Redis connection */ public static RedisConnection doGetConnection( RedisConnectionFactory factory, boolean allowCreate, boolean bind, boolean enableTransactionSupport) { Assert.notNull(factory, "No RedisConnectionFactory specified"); RedisConnectionHolder connHolder = (RedisConnectionHolder) TransactionSynchronizationManager.getResource(factory); if (connHolder != null) { if (enableTransactionSupport) { potentiallyRegisterTransactionSynchronisation(connHolder, factory); } return connHolder.getConnection(); } if (!allowCreate) { throw new IllegalArgumentException("No connection found and allowCreate = false"); } if (log.isDebugEnabled()) { log.debug("Opening RedisConnection"); } RedisConnection conn = factory.getConnection(); if (bind) { RedisConnection connectionToBind = conn; if (enableTransactionSupport && isActualNonReadonlyTransactionActive()) { connectionToBind = createConnectionProxy(conn, factory); } connHolder = new RedisConnectionHolder(connectionToBind); TransactionSynchronizationManager.bindResource(factory, connHolder); if (enableTransactionSupport) { potentiallyRegisterTransactionSynchronisation(connHolder, factory); } return connHolder.getConnection(); } return conn; }
private void unbindSession() { if (sessionFactory == null) { throw new IllegalStateException("No sessionFactory property provided"); } SessionHolder sessionHolder = (SessionHolder) TransactionSynchronizationManager.getResource(sessionFactory); try { if (!FlushMode.MANUAL.equals(sessionHolder.getSession().getFlushMode())) { sessionHolder.getSession().flush(); } } catch (Exception e) { e.printStackTrace(); } finally { TransactionSynchronizationManager.unbindResource(sessionFactory); SessionFactoryUtils.closeSession(sessionHolder.getSession()); } }
@Override protected void createCriteriaInstance() { { if (TransactionSynchronizationManager.hasResource(sessionFactory)) { participate = true; hibernateSession = ((SessionHolder) TransactionSynchronizationManager.getResource(sessionFactory)) .getSession(); } else { hibernateSession = sessionFactory.openSession(); } criteria = hibernateSession.createCriteria(targetClass); cacheCriteriaMapping(); criteriaMetaClass = GroovySystem.getMetaClassRegistry().getMetaClass(criteria.getClass()); } }
@Override public void afterCompletion(int status) { RestPostProcessorDelegate.LOG.info("Transaction completed"); try { if (status == STATUS_COMMITTED) { RestPostProcessorDelegate.LOG.info("Transaction was committed, sending events."); List<String> eventLog = (List<String>) TransactionSynchronizationManager.getResource(EVENT_LOG_KEY); eventLogSender.send(eventLog); } else { RestPostProcessorDelegate.LOG.info( "Transaction was not committed, status was " + status + ", not sending events."); } } catch (IOException e) { throw new RuntimeException("Failed to send the event log.", e); } finally { TransactionSynchronizationManager.unbindResource(EVENT_LOG_KEY); } }
/** * Actually obtain a JDBC Connection from the given DataSource. Same as {@link #getConnection}, * but throwing the original SQLException. * * <p>Is aware of a corresponding Connection bound to the current thread, for example when using * {@link DataSourceTransactionManager}. Will bind a Connection to the thread if transaction * synchronization is active (e.g. if in a JTA transaction). * * <p>Directly accessed by {@link TransactionAwareDataSourceProxy}. * * @param dataSource the DataSource to obtain Connections from * @return a JDBC Connection from the given DataSource * @throws SQLException if thrown by JDBC methods * @see #doReleaseConnection */ public static Connection doGetConnection(DataSource dataSource) throws SQLException { Assert.notNull(dataSource, "No DataSource specified"); ConnectionHolder conHolder = (ConnectionHolder) TransactionSynchronizationManager.getResource(dataSource); if (conHolder != null && (conHolder.hasConnection() || conHolder.isSynchronizedWithTransaction())) { conHolder.requested(); if (!conHolder.hasConnection()) { logger.debug("Fetching resumed JDBC Connection from DataSource"); conHolder.setConnection(dataSource.getConnection()); } return conHolder.getConnection(); } // Else we either got no holder or an empty thread-bound holder here. logger.debug("Fetching JDBC Connection from DataSource"); Connection con = dataSource.getConnection(); if (TransactionSynchronizationManager.isSynchronizationActive()) { logger.debug("Registering transaction synchronization for JDBC Connection"); // Use same Connection for further JDBC actions within the transaction. // Thread-bound object will get removed by synchronization at transaction completion. ConnectionHolder holderToUse = conHolder; if (holderToUse == null) { holderToUse = new ConnectionHolder(con); } else { holderToUse.setConnection(con); } holderToUse.requested(); TransactionSynchronizationManager.registerSynchronization( new ConnectionSynchronization(holderToUse, dataSource)); holderToUse.setSynchronizedWithTransaction(true); if (holderToUse != conHolder) { TransactionSynchronizationManager.bindResource(dataSource, holderToUse); } } return con; }
/** * Closes the given connection, created via the given factory if not managed externally (i.e. not * bound to the thread). * * @param conn the Redis connection to close * @param factory the Redis factory that the connection was created with */ public static void releaseConnection(RedisConnection conn, RedisConnectionFactory factory) { if (conn == null) { return; } RedisConnectionHolder connHolder = (RedisConnectionHolder) TransactionSynchronizationManager.getResource(factory); if (connHolder != null && connHolder.isTransactionSyncronisationActive()) { if (log.isDebugEnabled()) { log.debug("Redis Connection will be closed when transaction finished."); } return; } // Only release non-transactional/non-bound connections. if (!isConnectionTransactional(conn, factory)) { if (log.isDebugEnabled()) { log.debug("Closing Redis Connection"); } conn.close(); } }
/** * Actually close the given Connection, obtained from the given DataSource. Same as {@link * #releaseConnection}, but throwing the original SQLException. * * <p>Directly accessed by {@link TransactionAwareDataSourceProxy}. * * @param con the Connection to close if necessary (if this is <code>null</code>, the call will be * ignored) * @param dataSource the DataSource that the Connection was obtained from (may be <code>null * </code>) * @throws SQLException if thrown by JDBC methods * @see #doGetConnection */ public static void doReleaseConnection(Connection con, DataSource dataSource) throws SQLException { if (con == null) { return; } if (dataSource != null) { ConnectionHolder conHolder = (ConnectionHolder) TransactionSynchronizationManager.getResource(dataSource); if (conHolder != null && connectionEquals(conHolder, con)) { // It's the transactional Connection: Don't close it. conHolder.released(); return; } } // Leave the Connection open only if the DataSource is our // special SmartDataSoruce and it wants the Connection left open. if (!(dataSource instanceof SmartDataSource) || ((SmartDataSource) dataSource).shouldClose(con)) { logger.debug("Returning JDBC Connection to DataSource"); con.close(); } }
/** * Obtain a JMS Session that is synchronized with the current transaction, if any. * * @param connectionFactory the JMS ConnectionFactory to bind for (used as * TransactionSynchronizationManager key) * @param resourceFactory the ResourceFactory to use for extracting or creating JMS resources * @param startConnection whether the underlying JMS Connection approach should be started in * order to allow for receiving messages. Note that a reused Connection may already have been * started before, even if this flag is {@code false}. * @return the transactional Session, or {@code null} if none found * @throws JMSException in case of JMS failure */ public static Session doGetTransactionalSession( ConnectionFactory connectionFactory, ResourceFactory resourceFactory, boolean startConnection) throws JMSException { Assert.notNull(connectionFactory, "ConnectionFactory must not be null"); Assert.notNull(resourceFactory, "ResourceFactory must not be null"); JmsResourceHolder resourceHolder = (JmsResourceHolder) TransactionSynchronizationManager.getResource(connectionFactory); if (resourceHolder != null) { Session session = resourceFactory.getSession(resourceHolder); if (session != null) { if (startConnection) { Connection con = resourceFactory.getConnection(resourceHolder); if (con != null) { con.start(); } } return session; } if (resourceHolder.isFrozen()) { return null; } } if (!TransactionSynchronizationManager.isSynchronizationActive()) { return null; } JmsResourceHolder resourceHolderToUse = resourceHolder; if (resourceHolderToUse == null) { resourceHolderToUse = new JmsResourceHolder(connectionFactory); } Connection con = resourceFactory.getConnection(resourceHolderToUse); Session session = null; try { boolean isExistingCon = (con != null); if (!isExistingCon) { con = resourceFactory.createConnection(); resourceHolderToUse.addConnection(con); } session = resourceFactory.createSession(con); resourceHolderToUse.addSession(session, con); if (startConnection) { con.start(); } } catch (JMSException ex) { if (session != null) { try { session.close(); } catch (Throwable ex2) { // ignore } } if (con != null) { try { con.close(); } catch (Throwable ex2) { // ignore } } throw ex; } if (resourceHolderToUse != resourceHolder) { TransactionSynchronizationManager.registerSynchronization( new JmsResourceSynchronization( resourceHolderToUse, connectionFactory, resourceFactory.isSynchedLocalTransactionAllowed())); resourceHolderToUse.setSynchronizedWithTransaction(true); TransactionSynchronizationManager.bindResource(connectionFactory, resourceHolderToUse); } return session; }
private static DB doGetDB( Mongo mongo, String databaseName, UserCredentials credentials, boolean allowCreate) { DbHolder dbHolder = (DbHolder) TransactionSynchronizationManager.getResource(mongo); // Do we have a populated holder and TX sync active? if (dbHolder != null && !dbHolder.isEmpty() && TransactionSynchronizationManager.isSynchronizationActive()) { DB db = dbHolder.getDB(databaseName); // DB found but not yet synchronized if (db != null && !dbHolder.isSynchronizedWithTransaction()) { LOGGER.debug( "Registering Spring transaction synchronization for existing MongoDB {}.", databaseName); TransactionSynchronizationManager.registerSynchronization( new MongoSynchronization(dbHolder, mongo)); dbHolder.setSynchronizedWithTransaction(true); } if (db != null) { return db; } } // Lookup fresh database instance LOGGER.debug("Getting Mongo Database name=[{}]", databaseName); DB db = mongo.getDB(databaseName); boolean credentialsGiven = credentials.hasUsername() && credentials.hasPassword(); synchronized (db) { if (credentialsGiven && !db.isAuthenticated()) { String username = credentials.getUsername(); String password = credentials.hasPassword() ? credentials.getPassword() : null; if (!db.authenticate(username, password == null ? null : password.toCharArray())) { throw new CannotGetMongoDbConnectionException( "Failed to authenticate to database [" + databaseName + "], username = [" + username + "], password = [" + password + "]", databaseName, credentials); } } } // TX sync active, bind new database to thread if (TransactionSynchronizationManager.isSynchronizationActive()) { LOGGER.debug( "Registering Spring transaction synchronization for MongoDB instance {}.", databaseName); DbHolder holderToUse = dbHolder; if (holderToUse == null) { holderToUse = new DbHolder(databaseName, db); } else { holderToUse.addDB(databaseName, db); } TransactionSynchronizationManager.registerSynchronization( new MongoSynchronization(holderToUse, mongo)); holderToUse.setSynchronizedWithTransaction(true); if (holderToUse != dbHolder) { TransactionSynchronizationManager.bindResource(mongo, holderToUse); } } // Check whether we are allowed to return the DB. if (!allowCreate && !isDBTransactional(db, mongo)) { throw new IllegalStateException( "No Mongo DB bound to thread, " + "and configuration does not allow creation of non-transactional one here"); } return db; }
/* * @seeorg.springframework.jdbc.datasource.DataSourceTransactionManager# * doGetTransaction() */ public Object doGetTransaction() throws TransactionException { CompensatingTransactionHolderSupport holder = (CompensatingTransactionHolderSupport) TransactionSynchronizationManager.getResource(getTransactionSynchronizationKey()); return new CompensatingTransactionObject(holder); }