Refine search
/** * Enlist this application-managed EntityManager in the current transaction. */ private void enlistInCurrentTransaction() { // Resource local transaction, need to acquire the EntityTransaction, // start a transaction now and enlist a synchronization for commit or rollback later. EntityTransaction et = this.target.getTransaction(); et.begin(); if (logger.isDebugEnabled()) { logger.debug("Starting resource-local transaction on application-managed " + "EntityManager [" + this.target + "]"); } ExtendedEntityManagerSynchronization extendedEntityManagerSynchronization = new ExtendedEntityManagerSynchronization(this.target, this.exceptionTranslator); TransactionSynchronizationManager.bindResource(this.target, extendedEntityManagerSynchronization); TransactionSynchronizationManager.registerSynchronization(extendedEntityManagerSynchronization); } }
@Override @Nullable public Object remove(String name) { ScopedObjectsHolder scopedObjects = (ScopedObjectsHolder) TransactionSynchronizationManager.getResource(this); if (scopedObjects != null) { scopedObjects.destructionCallbacks.remove(name); return scopedObjects.scopedInstances.remove(name); } else { return null; } }
@Override public Object invoke(MethodInvocation invocation) throws Throwable { SessionFactory sf = getSessionFactory(); Assert.state(sf != null, "No SessionFactory set"); if (!TransactionSynchronizationManager.hasResource(sf)) { // New Session to be bound for the current method's scope... Session session = openSession(sf); try { TransactionSynchronizationManager.bindResource(sf, new SessionHolder(session)); return invocation.proceed(); } finally { SessionFactoryUtils.closeSession(session); TransactionSynchronizationManager.unbindResource(sf); } } else { // Pre-bound Session found -> simply proceed. return invocation.proceed(); } }
/** * Reactivate transaction synchronization for the current thread * and resume all given synchronizations. * @param suspendedSynchronizations a List of TransactionSynchronization objects */ private void doResumeSynchronization(List<TransactionSynchronization> suspendedSynchronizations) { TransactionSynchronizationManager.initSynchronization(); for (TransactionSynchronization synchronization : suspendedSynchronizations) { synchronization.resume(); TransactionSynchronizationManager.registerSynchronization(synchronization); } }
@Override public void put(final Object key, @Nullable final Object value) { if (TransactionSynchronizationManager.isSynchronizationActive()) { TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() { @Override public void afterCommit() { TransactionAwareCacheDecorator.this.targetCache.put(key, value); } }); } else { this.targetCache.put(key, value); } }
/** * Actually obtain a CCI Connection from the given ConnectionFactory. * Same as {@link #getConnection}, but throwing the original ResourceException. * <p>Is aware of a corresponding Connection bound to the current thread, for example * when using {@link CciLocalTransactionManager}. Will bind a Connection to the thread * if transaction synchronization is active (e.g. if in a JTA transaction). * <p>Directly accessed by {@link TransactionAwareConnectionFactoryProxy}. * @param cf the ConnectionFactory to obtain Connection from * @return a CCI Connection from the given ConnectionFactory * @throws ResourceException if thrown by CCI API methods * @see #doReleaseConnection */ public static Connection doGetConnection(ConnectionFactory cf) throws ResourceException { Assert.notNull(cf, "No ConnectionFactory specified"); ConnectionHolder conHolder = (ConnectionHolder) TransactionSynchronizationManager.getResource(cf); if (conHolder != null) { return conHolder.getConnection(); } logger.debug("Opening CCI Connection"); Connection con = cf.getConnection(); if (TransactionSynchronizationManager.isSynchronizationActive()) { conHolder = new ConnectionHolder(con); conHolder.setSynchronizedWithTransaction(true); TransactionSynchronizationManager.registerSynchronization(new ConnectionSynchronization(conHolder, cf)); TransactionSynchronizationManager.bindResource(cf, conHolder); } return con; }
(EntityManagerHolder) TransactionSynchronizationManager.getResource(emf); if (emHolder != null) { if (synchronizedWithTransaction) { if (!emHolder.isSynchronizedWithTransaction()) { if (TransactionSynchronizationManager.isActualTransactionActive()) { if (TransactionSynchronizationManager.isSynchronizationActive()) { Object transactionData = prepareTransaction(emHolder.getEntityManager(), emf); TransactionSynchronizationManager.registerSynchronization( new TransactionalEntityManagerSynchronization(emHolder, emf, transactionData, false)); emHolder.setSynchronizedWithTransaction(true); if (emHolder.isTransactionActive() && !emHolder.isOpen()) { if (!TransactionSynchronizationManager.isSynchronizationActive()) { return null; TransactionSynchronizationManager.unbindResource(emf); else if (!TransactionSynchronizationManager.isSynchronizationActive()) { if (synchronizedWithTransaction) { Object transactionData = prepareTransaction(em, emf); TransactionSynchronizationManager.registerSynchronization( new TransactionalEntityManagerSynchronization(emHolder, emf, transactionData, true)); emHolder.setSynchronizedWithTransaction(true); TransactionSynchronizationManager.registerSynchronization( new TransactionScopedEntityManagerSynchronization(emHolder, emf));
/** * Register a new transaction synchronization for the current thread. * Typically called by resource management code. * <p>Note that synchronizations can implement the * {@link org.springframework.core.Ordered} interface. * They will be executed in an order according to their order value (if any). * @param synchronization the synchronization object to register * @throws IllegalStateException if transaction synchronization is not active * @see org.springframework.core.Ordered */ public static void registerSynchronization(TransactionSynchronization synchronization) throws IllegalStateException { Assert.notNull(synchronization, "TransactionSynchronization must not be null"); if (!isSynchronizationActive()) { throw new IllegalStateException("Transaction synchronization is not active"); } synchronizations.get().add(synchronization); }
/** * 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, @Nullable DataSource dataSource, int timeout) throws SQLException { Assert.notNull(stmt, "No Statement specified"); ConnectionHolder holder = null; if (dataSource != null) { 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 static MongoDatabase doGetMongoDatabase(@Nullable String dbName, MongoDbFactory factory, SessionSynchronization sessionSynchronization) { Assert.notNull(factory, "Factory must not be null!"); if (!TransactionSynchronizationManager.isSynchronizationActive()) { return StringUtils.hasText(dbName) ? factory.getDb(dbName) : factory.getDb(); } ClientSession session = doGetSession(factory, sessionSynchronization); if (session == null) { return StringUtils.hasText(dbName) ? factory.getDb(dbName) : factory.getDb(); } MongoDbFactory factoryToUse = factory.withSession(session); return StringUtils.hasText(dbName) ? factoryToUse.getDb(dbName) : factoryToUse.getDb(); }
/** * 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) { Assert.notNull(connFactory, "No RedisConnectionFactory specified"); RedisConnectionHolder connHolder = (RedisConnectionHolder) TransactionSynchronizationManager .getResource(connFactory); return (connHolder != null && conn == connHolder.getConnection()); }
tt.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW); given(manager.getTransaction()).willReturn(tx); assertTrue(!TransactionSynchronizationManager.hasResource(factory)); assertTrue(!TransactionSynchronizationManager.isSynchronizationActive()); TransactionSynchronizationManager.bindResource(factory, new EntityManagerHolder(manager)); TransactionSynchronizationManager.unbindResource(factory); assertTrue(!TransactionSynchronizationManager.hasResource(factory)); assertTrue(!TransactionSynchronizationManager.isSynchronizationActive()); verify(manager).flush(); verify(manager).close();
@Test public void testTransactionFlush() { given(manager.getTransaction()).willReturn(tx); assertTrue(!TransactionSynchronizationManager.hasResource(factory)); assertTrue(!TransactionSynchronizationManager.isSynchronizationActive()); tt.execute(new TransactionCallbackWithoutResult() { @Override public void doInTransactionWithoutResult(TransactionStatus status) { assertTrue(TransactionSynchronizationManager.hasResource(factory)); status.flush(); } }); assertTrue(!TransactionSynchronizationManager.hasResource(factory)); assertTrue(!TransactionSynchronizationManager.isSynchronizationActive()); verify(tx).commit(); verify(manager).flush(); verify(manager).close(); }
@Test public void testTransactionCommitWithPrebound() { given(manager.getTransaction()).willReturn(tx); final List<String> l = new ArrayList<>(); l.add("test"); assertTrue(!TransactionSynchronizationManager.hasResource(factory)); assertTrue(!TransactionSynchronizationManager.isSynchronizationActive()); TransactionSynchronizationManager.bindResource(factory, new EntityManagerHolder(manager)); try { Object result = tt.execute(new TransactionCallback() { @Override public Object doInTransaction(TransactionStatus status) { assertTrue(TransactionSynchronizationManager.hasResource(factory)); assertTrue(TransactionSynchronizationManager.isSynchronizationActive()); EntityManagerFactoryUtils.getTransactionalEntityManager(factory); return l; } }); assertSame(l, result); assertTrue(TransactionSynchronizationManager.hasResource(factory)); assertTrue(!TransactionSynchronizationManager.isSynchronizationActive()); } finally { TransactionSynchronizationManager.unbindResource(factory); } verify(tx).begin(); verify(tx).commit(); }
@Test public void testPropertiesForSharedEntityManager2() { Properties props = new Properties(); props.put("foo", "bar"); EntityManager em = mock(EntityManager.class); // only one call made - the first EM definition wins (in this case the one w/o the properties) given(mockEmf.createEntityManager()).willReturn(em); given(em.getDelegate()).willReturn(new Object(), 2); given(em.isOpen()).willReturn(true); PersistenceAnnotationBeanPostProcessor pabpp = new MockPersistenceAnnotationBeanPostProcessor(); DefaultPrivatePersistenceContextFieldWithProperties transactionalFieldWithProperties = new DefaultPrivatePersistenceContextFieldWithProperties(); DefaultPrivatePersistenceContextField transactionalField = new DefaultPrivatePersistenceContextField(); pabpp.postProcessProperties(null, transactionalFieldWithProperties, "bean1"); pabpp.postProcessProperties(null, transactionalField, "bean2"); assertNotNull(transactionalFieldWithProperties.em); assertNotNull(transactionalField.em); // the EM w/o properties will be created assertNotNull(transactionalField.em.getDelegate()); // bind em to the thread now since it's created try { TransactionSynchronizationManager.bindResource(mockEmf, new EntityManagerHolder(em)); assertNotNull(transactionalFieldWithProperties.em.getDelegate()); verify(em).close(); } finally { TransactionSynchronizationManager.unbindResource(mockEmf); } }
@Test public void testTransactionRollbackWithPreboundAndPropagationSupports() { tt.setPropagationBehavior(TransactionDefinition.PROPAGATION_SUPPORTS); assertTrue(!TransactionSynchronizationManager.hasResource(factory)); assertTrue(!TransactionSynchronizationManager.isSynchronizationActive()); TransactionSynchronizationManager.bindResource(factory, new EntityManagerHolder(manager)); try { tt.execute(new TransactionCallback() { @Override public Object doInTransaction(TransactionStatus status) { assertTrue(TransactionSynchronizationManager.hasResource(factory)); assertTrue(TransactionSynchronizationManager.isSynchronizationActive()); assertTrue(!status.isNewTransaction()); EntityManagerFactoryUtils.getTransactionalEntityManager(factory).flush(); status.setRollbackOnly(); return null; } }); assertTrue(TransactionSynchronizationManager.hasResource(factory)); assertTrue(!TransactionSynchronizationManager.isSynchronizationActive()); } finally { TransactionSynchronizationManager.unbindResource(factory); } verify(manager).flush(); verify(manager).clear(); }
@Test public void testWriteAndFlushSunnyDay() throws Exception { EntityManager em = mock(EntityManager.class,"em"); em.contains("foo"); em.contains("bar"); em.merge("bar"); em.flush(); TransactionSynchronizationManager.bindResource(emf, new EntityManagerHolder(em)); List<String> items = Arrays.asList(new String[] { "foo", "bar" }); writer.write(items); TransactionSynchronizationManager.unbindResource(emf); }
@Test public void testTransactionRollbackWithPropagationSupports() { given(manager.isOpen()).willReturn(true); tt.setPropagationBehavior(TransactionDefinition.PROPAGATION_SUPPORTS); assertTrue(!TransactionSynchronizationManager.hasResource(factory)); assertTrue(!TransactionSynchronizationManager.isSynchronizationActive()); tt.execute(new TransactionCallback() { @Override public Object doInTransaction(TransactionStatus status) { assertTrue(!TransactionSynchronizationManager.hasResource(factory)); assertTrue(TransactionSynchronizationManager.isSynchronizationActive()); assertTrue(!status.isNewTransaction()); EntityManagerFactoryUtils.getTransactionalEntityManager(factory).flush(); status.setRollbackOnly(); return null; } }); assertTrue(!TransactionSynchronizationManager.hasResource(factory)); assertTrue(!TransactionSynchronizationManager.isSynchronizationActive()); verify(manager).flush(); verify(manager).close(); }
given(mockEm.isOpen()).willReturn(true); assertFalse(proxy.contains(o)); TransactionSynchronizationManager.bindResource(mockEmf, new EntityManagerHolder(mockEm)); try { assertSame(mockEm, emProxy.getTargetEntityManager()); TransactionSynchronizationManager.unbindResource(mockEmf); assertTrue(TransactionSynchronizationManager.getResourceMap().isEmpty()); verify(mockEm).contains(o); verify(mockEm).close();
@Override public Object doInTransaction(TransactionStatus status) { assertTrue(!TransactionSynchronizationManager.hasResource(factory)); assertTrue(TransactionSynchronizationManager.isSynchronizationActive()); assertTrue(!status.isNewTransaction()); EntityManagerFactoryUtils.getTransactionalEntityManager(factory).flush(); return l; } });