/** 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"); } }
/** * 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; }
/** * 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; }
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); }
public static void doBeforeCommit(final InvokationCallback invokationCallback) { if (TransactionSynchronizationManager.isActualTransactionActive()) { TransactionSynchronizationManager.registerSynchronization( new TransactionSynchronizationAdapter() { public void beforeCommit(boolean readOnly) { invokationCallback.invoke(); } }); } else { // invoke now invokationCallback.invoke(); } }
public static void afterCommit(final Runnable action) { if (TransactionSynchronizationManager.isActualTransactionActive()) { TransactionSynchronizationManager.registerSynchronization( new TransactionSynchronizationAdapter() { @Override public void afterCommit() { action.run(); } }); } else { action.run(); } }
public void registerSynchronization(final Synchronization synchronization) { TransactionSynchronizationManager.registerSynchronization( new TransactionSynchronizationAdapter() { public void afterCompletion(int state) { System.out.println(" ---------------------------------------- "); System.out.println(synchronization); System.out.println(" ---------------------------------------- "); synchronization.afterCompletion(state); } public void beforeCompletion() { synchronization.beforeCompletion(); } }); }
/** * this method checks if there is a transaction active and registers an afterCommit invokation of * the InvokationCallback. if there is no transaction active it invokes the InvokationCallback * immediately. * * @param invokationCallback */ public static void doAfterCommit(final InvokationCallback invokationCallback) { // currentlly supports spring synchronization if (TransactionSynchronizationManager.isActualTransactionActive()) { TransactionSynchronizationManager.registerSynchronization( new TransactionSynchronizationAdapter() { @Override public void afterCommit() { invokationCallback.invoke(); } }); } else { // invoke now invokationCallback.invoke(); } }
private static void potentiallyRegisterTransactionSynchronisation( RedisConnectionHolder connHolder, final RedisConnectionFactory factory) { if (isActualNonReadonlyTransactionActive()) { if (!connHolder.isTransactionSyncronisationActive()) { connHolder.setTransactionSyncronisationActive(true); RedisConnection conn = connHolder.getConnection(); conn.multi(); TransactionSynchronizationManager.registerSynchronization( new RedisTransactionSynchronizer(connHolder, conn, factory)); } } }
@EventListener public void blogAddedTransactionalOldSchool(final BlogAddedEvent blogAddedEvent) { // Note: *Old school* transaction handling before Spring 4.2 if (TransactionSynchronizationManager .isActualTransactionActive()) { // To not fail with "java.lang.IllegalStateException: // Transaction synchronization is not active" TransactionSynchronizationManager.registerSynchronization( new TransactionSynchronizationAdapter() { @Override public void afterCommit() { internalSendBlogAddedNotification(blogAddedEvent); } }); } else { log.warn("No active transaction found. Sending notification immediately."); internalSendBlogAddedNotification(blogAddedEvent); } }
@Override public TranslationProcess execute() { final TranslationProcess process = this.process; final Integer i = Integer.valueOf(getParams().getAttributes()[0]); TransactionTemplate transactionTemplate = new TransactionTemplate(txManager); transactionTemplate.execute( status -> { DictionaryWord word = process.getWords().get(i); String filename = fileService.createFile(word.toString()); TransactionSynchronizationManager.registerSynchronization( new FileRollbackHandler(filename)); repository.addWord(word); return null; // To change body of implemented methods use File | Settings | File // Templates. }); return process; }
/** * This implementation delegates to setParameterInternal, passing in a transaction-synchronized * LobCreator for the LobHandler of this type. * * @see #setParameterInternal */ public final void setParameter(PreparedStatement ps, int i, Object parameter, String jdbcType) throws SQLException { if (!TransactionSynchronizationManager.isSynchronizationActive()) { throw new IllegalStateException( "Spring transaction synchronization needs to be active for " + "setting values in iBATIS TypeHandlers that delegate to a Spring LobHandler"); } final LobCreator lobCreator = this.lobHandler.getLobCreator(); try { setParameterInternal(ps, i, parameter, jdbcType, lobCreator); } catch (IOException ex) { throw new SQLException("I/O errors during LOB access: " + ex.getMessage()); } TransactionSynchronizationManager.registerSynchronization( new LobCreatorSynchronization(lobCreator)); }
/** * 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; }
/** * 将规则注册入规则容器中 <功能详细描述> * * @param spRule [参数说明] * @return void [返回类型说明] * @exception throws [异常类型] [异常说明] * @see [类、类#方法、类#成员] */ @Transactional public Rule registeRule(SimplePersistenceRule spRule) { if (spRule == null || StringUtils.isEmpty(spRule.getRule()) || StringUtils.isEmpty(spRule.getServiceType()) || spRule.getRuleType() == null) { throw new RuleRegisteException("spRule or rule or serviceType or ruleType is null"); } RuleRegister<? extends Rule> ruleRegisterTemp = ruleRegisterMap.get(spRule.getRuleType()); if (ruleRegisterTemp == null) { throw new RuleRegisteException( "ruleType:{} RuleRegister not exist.", spRule.getRuleType().toString()); } // 调用对应注册器方法,将规则注册入容器中 final Rule realRule = ruleRegisterTemp.registe(spRule); if (realRule != null) { if (TransactionSynchronizationManager.isSynchronizationActive()) { // 如果在事务逻辑中执行 TransactionSynchronizationManager.registerSynchronization( new TransactionSynchronizationAdapter() { @Override public void afterCommit() { putInCache(realRule, true); } }); } else { // 如果在非事务中执行 putInCache(realRule, true); } } else { throw new RuleRegisteException( "ruleType:{} RuleRegister call registe return null realRule.", spRule.getRuleType().toString()); } return realRule; }
/** * 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; }
public void registerTransactionSynchronization(TransactionSynchronization ts) { TransactionSynchronizationManager.registerSynchronization( new SpringTransactionSynchronizationAdapter(ts)); }
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; }
// ============================================================================================ // publish event // ============================================================================================ public void registerSynchronization(Synchronization synchronization) { SynchronizationNotification synchronizationNotification = new SynchronizationNotification(synchronization); TransactionSynchronizationManager.registerSynchronization(synchronizationNotification); }