@Test public void testInvalidIsolation() { tt.setIsolationLevel(TransactionDefinition.ISOLATION_SERIALIZABLE); given(manager.isOpen()).willReturn(true); try { tt.execute(new TransactionCallbackWithoutResult() { @Override protected void doInTransactionWithoutResult(TransactionStatus status) { } }); fail("Should have thrown InvalidIsolationLevelException"); } catch (InvalidIsolationLevelException ex) { // expected } verify(manager).close(); }
/** * This implementation invokes the standard JPA {@code Transaction.begin} * method. Throws an InvalidIsolationLevelException if a non-default isolation * level is set. * <p>This implementation does not return any transaction data Object, since there * is no state to be kept for a standard JPA transaction. Hence, subclasses do not * have to care about the return value ({@code null}) of this implementation * and are free to return their own transaction data Object. * @see javax.persistence.EntityTransaction#begin * @see org.springframework.transaction.InvalidIsolationLevelException * @see #cleanupTransaction */ @Override public Object beginTransaction(EntityManager entityManager, TransactionDefinition definition) throws PersistenceException, SQLException, TransactionException { if (definition.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT) { throw new InvalidIsolationLevelException(getClass().getSimpleName() + " does not support custom isolation levels due to limitations in standard JPA. " + "Specific arrangements may be implemented in custom JpaDialect variants."); } entityManager.getTransaction().begin(); return null; }
@Override public Object beginTransaction(EntityManager entityManager, TransactionDefinition definition) throws PersistenceException, SQLException, TransactionException { Session session = getSession(entityManager); if (definition.getTimeout() != TransactionDefinition.TIMEOUT_DEFAULT) { session.getTransaction().setTimeout(definition.getTimeout()); } boolean isolationLevelNeeded = (definition.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT); Integer previousIsolationLevel = null; Connection preparedCon = null; if (isolationLevelNeeded || definition.isReadOnly()) { if (this.prepareConnection) { preparedCon = HibernateConnectionHandle.doGetConnection(session); previousIsolationLevel = DataSourceUtils.prepareConnectionForTransaction(preparedCon, definition); } else if (isolationLevelNeeded) { throw new InvalidIsolationLevelException(getClass().getSimpleName() + " does not support custom isolation levels since the 'prepareConnection' flag is off. " + "This is the case on Hibernate 3.6 by default; either switch that flag at your own risk " + "or upgrade to Hibernate 4.x, with 4.2+ recommended."); } } // Standard JPA transaction begin call for full JPA context setup... entityManager.getTransaction().begin(); // Adapt flush mode and store previous isolation level, if any. FlushMode previousFlushMode = prepareFlushMode(session, definition.isReadOnly()); return new SessionTransactionData(session, previousFlushMode, preparedCon, previousIsolationLevel); }
protected void applyIsolationLevel(JiniTransactionObject txObject, int isolationLevel) throws InvalidIsolationLevelException { if (isolationLevel != TransactionDefinition.ISOLATION_DEFAULT) { if (!suppportsCustomIsolationLevel()) throw new InvalidIsolationLevelException(getClass().getName() + " does not support custom isolation levels"); if (isolationLevel == TransactionDefinition.ISOLATION_SERIALIZABLE) throw new InvalidIsolationLevelException("Jini Transaction Manager does not support serializable isolation level"); } }
/** {@inheritDoc} */ @Override protected void doBegin(Object transaction, TransactionDefinition definition) throws TransactionException { if (definition.getIsolationLevel() == TransactionDefinition.ISOLATION_READ_UNCOMMITTED) throw new InvalidIsolationLevelException("Ignite does not support READ_UNCOMMITTED isolation level."); IgniteTransactionObject txObj = (IgniteTransactionObject)transaction; Transaction tx = null; try { if (txObj.getTransactionHolder() == null || txObj.getTransactionHolder().isSynchronizedWithTransaction()) { long timeout = ignite.configuration().getTransactionConfiguration().getDefaultTxTimeout(); if (definition.getTimeout() > 0) timeout = TimeUnit.SECONDS.toMillis(definition.getTimeout()); Transaction newTx = ignite.transactions().txStart(transactionConcurrency, convertToIgniteIsolationLevel(definition.getIsolationLevel()), timeout, 0); if (log.isDebugEnabled()) log.debug("Started Ignite transaction: " + newTx); txObj.setTransactionHolder(new IgniteTransactionHolder(newTx), true); } txObj.getTransactionHolder().setSynchronizedWithTransaction(true); txObj.getTransactionHolder().setTransactionActive(true); tx = txObj.getTransactionHolder().getTransaction(); // Bind the session holder to the thread. if (txObj.isNewTransactionHolder()) TransactionSynchronizationManager.bindResource(this.ignite, txObj.getTransactionHolder()); } catch (Exception ex) { if (tx != null) tx.close(); throw new CannotCreateTransactionException("Could not create Ignite transaction", ex); } }
/** */ public void testUnsupportedIsolationLevel() { IgniteCache<Integer, String> c = grid().cache(CACHE_NAME); try { service.putWithUnsupportedIsolationLevel(c); } catch (InvalidIsolationLevelException e) { assertEquals("Ignite does not support READ_UNCOMMITTED isolation level.", e.getMessage()); } assertEquals(0, c.size()); }
protected void doBegin(Object transaction, TransactionDefinition definition) { if (definition.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT) { throw new InvalidIsolationLevelException("JMS does not support an isolation level concept"); } JmsTransactionObject txObject = (JmsTransactionObject) transaction; Connection con = null; Session session = null; try { con = createConnection(); session = createSession(con); if (logger.isDebugEnabled()) { logger.debug("Created JMS transaction on Session [" + session + "] from Connection [" + con + "]"); } txObject.setResourceHolder(new JmsResourceHolder(getConnectionFactory(), con, session)); txObject.getResourceHolder().setSynchronizedWithTransaction(true); int timeout = determineTimeout(definition); if (timeout != TransactionDefinition.TIMEOUT_DEFAULT) { txObject.getResourceHolder().setTimeoutInSeconds(timeout); } TransactionSynchronizationManager.bindResource( getConnectionFactory(), txObject.getResourceHolder()); } catch (Throwable ex) { if (con != null) { try { con.close(); } catch (Throwable ex2) { // ignore } } throw new CannotCreateTransactionException("Could not create JMS transaction", ex); } }
@Override protected void doBegin(Object transaction, TransactionDefinition transactionDefinition) throws TransactionException { if (transactionDefinition.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT) { throw new InvalidIsolationLevelException( "JCR does not support an isolation level concept"); } // XASession session = null; XAResource session = null; try { JcrTransactionObject txObject = (JcrTransactionObject) transaction; if (txObject.getSessionHolder() == null) { // get the new session Session newSession = sessionFactory.getSession(); // make sure we have an XASession // if (!(newSession instanceof XASession)) if (!(newSession instanceof XAResource)) throw new IllegalArgumentException( "transactions are not supported by your Jcr Repository"); LOG.debug("Opened new session [" + newSession + "] for JCR transaction"); txObject.setSessionHolder(new UserTxSessionHolder(newSession), true); } UserTxSessionHolder sessionHolder = txObject.getSessionHolder(); sessionHolder.setSynchronizedWithTransaction(true); // session = (XASession) sessionHolder.getSession(); session = (XAResource) sessionHolder.getSession(); /* * We have no notion of flushing inside a JCR session if * (transactionDefinition.isReadOnly() && * txObject.isNewSessionHolder()) { sessionHolder.setReadOnly(true); * } if (!transactionDefinition.isReadOnly() && * !txObject.isNewSessionHolder()) { if (sessionHolder.isReadOnly()) * { sessionHolder.setReadOnly(false); } } */ // start the transaction sessionHolder.getTransaction().begin(); // Register transaction timeout. if (transactionDefinition.getTimeout() != TransactionDefinition.TIMEOUT_DEFAULT) { txObject.getSessionHolder().setTimeoutInSeconds( transactionDefinition.getTimeout()); } // Bind the session holder to the thread. if (txObject.isNewSessionHolder()) { TransactionSynchronizationManager.bindResource( getSessionFactory(), sessionHolder); } } catch (Exception ex) { SessionFactoryUtils.releaseSession((Session) session, getSessionFactory()); throw new CannotCreateTransactionException( "Could not open JCR session for transaction", ex); } }
/** * Apply the given transaction isolation level. The default implementation * will throw an exception for any level other than ISOLATION_DEFAULT. * <p>To be overridden in subclasses for specific JTA implementations, * as alternative to overriding the full {@link #doJtaBegin} method. * @param txObject the JtaTransactionObject containing the UserTransaction * @param isolationLevel isolation level taken from transaction definition * @throws InvalidIsolationLevelException if the given isolation level * cannot be applied * @throws SystemException if thrown by the JTA implementation * @see #doJtaBegin * @see JtaTransactionObject#getUserTransaction() * @see #getTransactionManager() */ protected void applyIsolationLevel(JtaTransactionObject txObject, int isolationLevel) throws InvalidIsolationLevelException, SystemException { if (!this.allowCustomIsolationLevels && isolationLevel != TransactionDefinition.ISOLATION_DEFAULT) { throw new InvalidIsolationLevelException( "JtaTransactionManager does not support custom isolation levels by default - " + "switch 'allowCustomIsolationLevels' to 'true'"); } }
/** * This implementation invokes the standard JPA {@code Transaction.begin} * method. Throws an InvalidIsolationLevelException if a non-default isolation * level is set. * <p>This implementation does not return any transaction data Object, since there * is no state to be kept for a standard JPA transaction. Hence, subclasses do not * have to care about the return value ({@code null}) of this implementation * and are free to return their own transaction data Object. * @see javax.persistence.EntityTransaction#begin * @see org.springframework.transaction.InvalidIsolationLevelException * @see #cleanupTransaction */ public Object beginTransaction(EntityManager entityManager, TransactionDefinition definition) throws PersistenceException, SQLException, TransactionException { if (definition.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT) { throw new InvalidIsolationLevelException(getClass().getSimpleName() + " does not support custom isolation levels due to limitations in standard JPA. " + "Specific arrangements may be implemented in custom JpaDialect variants."); } entityManager.getTransaction().begin(); return null; }