/** * * @param auth * @return */ @RequestMapping(path = "/login", method = RequestMethod.POST, consumes = {"application/json"}) public ResponseEntity<String> loginAction(@RequestBody LoginDTO auth) { boolean isLoginSuccessful; try { isLoginSuccessful = authenticationService.login(auth.getLogin(), auth.getPassword()); if(isLoginSuccessful) { AppUser appUser = authenticationService.getLoggedUser(); UUID token = UUID.randomUUID(); UserDTO userDTO = new UserDTO(appUser.getId(), appUser.getEmail(), appUser.getFirstName(), appUser.getLastName(), token.toString()); authTokenCache.addAuthToken(token, appUser); return ResponseEntity.ok(gson.toJsonTree(userDTO).toString()); } } catch(CannotCreateTransactionException | PersistenceException | DatabaseException e) { return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(null); } return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(null); }
/** * Test behavior if the first operation on a connection (getAutoCommit) throws SQLException. */ @Test public void testTransactionWithExceptionOnBegin() throws Exception { willThrow(new SQLException("Cannot begin")).given(con).getAutoCommit(); TransactionTemplate tt = new TransactionTemplate(tm); try { tt.execute(new TransactionCallbackWithoutResult() { @Override protected void doInTransactionWithoutResult(TransactionStatus status) { // something transactional } }); fail("Should have thrown CannotCreateTransactionException"); } catch (CannotCreateTransactionException ex) { // expected } assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds)); verify(con).close(); }
@Override protected void doBegin(final Object transaction, final TransactionDefinition definition) { final FcrepoResponse response; final InputStream is = null; final String contentType = null; final FcrepoTransactionObject tx = (FcrepoTransactionObject)transaction; if (tx.getSessionId() == null) { try { response = getClient().post(URI.create(baseUrl + TRANSACTION)) .body(is, contentType).perform(); } catch (final FcrepoOperationFailedException ex) { LOGGER.debug("HTTP Operation failed: ", ex); throw new CannotCreateTransactionException("Could not create fcrepo transaction"); } if (response != null && response.getLocation() != null) { tx.setSessionId(response.getLocation().toString().substring(baseUrl.length() + 1)); } else { throw new CannotCreateTransactionException("Invalid response while creating transaction"); } } }
@Test (expected = CannotCreateTransactionException.class) public void testTransactionBeginError() throws FcrepoOperationFailedException { final String baseUrl = "http://localhost:8080/rest"; final String tx = "tx:1234567890"; final URI beginUri = URI.create(baseUrl + FcrepoConstants.TRANSACTION); final FcrepoTransactionManager txMgr = new FcrepoTransactionManager(); txMgr.setBaseUrl(baseUrl); TestUtils.setField(txMgr, "fcrepoClient", mockClient); final TransactionTemplate transactionTemplate = new TransactionTemplate(txMgr); final DefaultTransactionDefinition txDef = new DefaultTransactionDefinition( TransactionDefinition.PROPAGATION_REQUIRED); transactionTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED); transactionTemplate.afterPropertiesSet(); when(mockPostBuilder.perform()).thenThrow( new FcrepoOperationFailedException(beginUri, 400, "Bad Request")); txMgr.getTransaction(txDef); }
@Test (expected = CannotCreateTransactionException.class) public void testTransactionBeginNoLocationError() throws FcrepoOperationFailedException { final String baseUrl = "http://localhost:8080/rest"; final String tx = "tx:1234567890"; final URI beginUri = URI.create(baseUrl + FcrepoConstants.TRANSACTION); final FcrepoTransactionManager txMgr = new FcrepoTransactionManager(); txMgr.setBaseUrl(baseUrl); TestUtils.setField(txMgr, "fcrepoClient", mockClient); final TransactionTemplate transactionTemplate = new TransactionTemplate(txMgr); final DefaultTransactionDefinition txDef = new DefaultTransactionDefinition( TransactionDefinition.PROPAGATION_REQUIRED); transactionTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED); transactionTemplate.afterPropertiesSet(); when(mockPostBuilder.perform()).thenReturn( new FcrepoResponse(beginUri, 201, emptyMap(), null)); txMgr.getTransaction(txDef); }
@Test (expected = CannotCreateTransactionException.class) public void testTransactionNullResponseError() throws FcrepoOperationFailedException { final String baseUrl = "http://localhost:8080/rest"; final String tx = "tx:1234567890"; final URI beginUri = URI.create(baseUrl + FcrepoConstants.TRANSACTION); final FcrepoTransactionManager txMgr = new FcrepoTransactionManager(); txMgr.setBaseUrl(baseUrl); TestUtils.setField(txMgr, "fcrepoClient", mockClient); final TransactionTemplate transactionTemplate = new TransactionTemplate(txMgr); final DefaultTransactionDefinition txDef = new DefaultTransactionDefinition( TransactionDefinition.PROPAGATION_REQUIRED); transactionTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED); transactionTemplate.afterPropertiesSet(); when(mockPostBuilder.perform()).thenReturn(null); txMgr.getTransaction(txDef); }
/** * HA算法<br/> * 目前通过简单执行时间差判断是否 进行切换数据源重试,如果在设定的过期时间内则可以重试 * @param transaction * @param definition * @throws Throwable */ protected void tryDoBegin(Object transaction, TransactionDefinition definition) { //尝试开启事务的时间必须记录在线程变量,如果记录在方法栈,则会无限递归 Long beginTime = thread_tran_begin_time.get(); if(beginTime == null) { beginTime = System.currentTimeMillis(); thread_tran_begin_time.set(beginTime); } try{ super.doBegin(transaction, definition); }catch (CannotCreateTransactionException ex) { long time = System.currentTimeMillis() -beginTime; logger.error("获取连接错误!超时时间"+time/1000,ex); DataSource ds = this.getDataSource(); if(ds instanceof DynamicMysqlDataSource){ //移除不可用的数据源 ((DynamicMysqlDataSource)ds).removeSlaveDataSource(); } //如果开启事务的时间不超过限制时间并且出错了,则更换数据源重试 if(time < beginTransactionTimeOut*1000){ tryDoBegin(transaction, definition); }else{ throw ex; } }finally{ thread_tran_begin_time.remove(); DynamicMysqlDataSource.cleanLocalDataSource(); } }
/** * This implementation returns a JtaTransactionObject instance for the * JTA UserTransaction. * <p>The UserTransaction object will either be looked up freshly for the * current transaction, or the cached one looked up at startup will be used. * The latter is the default: Most application servers use a shared singleton * UserTransaction that can be cached. Turn off the "cacheUserTransaction" * flag to enforce a fresh lookup for every transaction. * @see #setCacheUserTransaction */ @Override protected Object doGetTransaction() { UserTransaction ut = getUserTransaction(); if (ut == null) { throw new CannotCreateTransactionException("No JTA UserTransaction available - " + "programmatic PlatformTransactionManager.getTransaction usage not supported"); } if (!this.cacheUserTransaction) { ut = lookupUserTransaction( this.userTransactionName != null ? this.userTransactionName : DEFAULT_USER_TRANSACTION_NAME); } return doGetJtaTransaction(ut); }
/** * * @param registration * @return */ @RequestMapping(path = "/register", method = RequestMethod.POST, consumes = {"application/json"}) public ResponseEntity<String> registerAction(@RequestBody RegistrationDTO registration) { try { registrationService.register(registration); AppUser appUser = authenticationService.getLoggedUser(); UUID token = UUID.randomUUID(); UserDTO userDTO = new UserDTO(appUser.getId(), appUser.getEmail(), appUser.getFirstName(), appUser.getLastName(), token.toString()); authTokenCache.addAuthToken(token, appUser); return ResponseEntity.ok(gson.toJsonTree(userDTO).toString()); } catch(CannotCreateTransactionException | PersistenceException | DatabaseException e) { return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("MUJ POKUS"); } }
@Override protected Transaction<RedisTemplate> beginTransactionInternal() { try { redisTemplate.multi(); } catch (Exception e) { throw new CannotCreateTransactionException("Error starting Redis transaction: " + e.getMessage(), e); } return new RedisTransaction(redisTemplate); }
/** * Simulate a transaction infrastructure failure. * Shouldn't invoke target method. */ @Test public void cannotCreateTransaction() throws Exception { TransactionAttribute txatt = new DefaultTransactionAttribute(); Method m = getNameMethod; MapTransactionAttributeSource tas = new MapTransactionAttributeSource(); tas.register(m, txatt); PlatformTransactionManager ptm = mock(PlatformTransactionManager.class); // Expect a transaction CannotCreateTransactionException ex = new CannotCreateTransactionException("foobar", null); given(ptm.getTransaction(txatt)).willThrow(ex); TestBean tb = new TestBean() { @Override public String getName() { throw new UnsupportedOperationException( "Shouldn't have invoked target method when couldn't create transaction for transactional method"); } }; ITestBean itb = (ITestBean) advised(tb, ptm, tas); try { itb.getName(); fail("Shouldn't have invoked method"); } catch (CannotCreateTransactionException thrown) { assertTrue(thrown == ex); } }
/** * This implementation creates a JDBC 3.0 Savepoint and returns it. * @see java.sql.Connection#setSavepoint */ @Override public Object createSavepoint() throws TransactionException { ConnectionHolder conHolder = getConnectionHolderForSavepoint(); try { if (!conHolder.supportsSavepoints()) { throw new NestedTransactionNotSupportedException( "Cannot create a nested transaction because savepoints are not supported by your JDBC driver"); } return conHolder.createSavepoint(); } catch (SQLException ex) { throw new CannotCreateTransactionException("Could not create JDBC savepoint", ex); } }
/** * Creates a new Lock Manager based on the {@link com.j_spaces.map.IMap}. */ public LockManager(IMap map) { this.map = map; this.masterSpace = map.getMasterSpace(); try { transactionManagerProvider = new DistributedTransactionManagerProvider(); } catch (TransactionException e) { throw new CannotCreateTransactionException("Failed to obtain transaction lock manager", e); } templatePool = new ArrayBlockingQueue<SpaceMapEntry>(1000); for (int i = 0; i < 1000; i++) { templatePool.add(MapEntryFactory.create()); } }
private Transaction getTransaction(long timeout) throws CannotCreateTransactionException { Transaction.Created tCreated; try { tCreated = TransactionFactory.create(transactionManagerProvider.getTransactionManager(), timeout); } catch (Exception e) { throw new CannotCreateTransactionException("Failed to create lock transaction", e); } return tCreated.transaction; }
@Override public UserDetails loadUserByUsername(String userName) throws AuthenticationException, DataAccessException { User user = null; try { // Return member from DB and populate roles. user = (User) userService.getUserByUserName(userName); if (user == null) { if (logger.isDebugEnabled()) { logger.debug("User name " + userName + " is missing in database !!!"); } throw new BadCredentialsException(MessageSourceUtils.getMessage(authenticationMessageSource, AuthenticationMessages.class, AuthenticationMessages.AUTHENTICATION_FAILED.name())); } user.setAuthorities(AuthenticationUtils.toGrantedAuthority((User) user)); logger.trace("User: " + user.getUsername() + " grantedAuthorities: " + user.getAuthorities()); } catch (CannotCreateTransactionException e) { logger.error("No connection to the database. Exception: " + e.getMessage()); if (logger.isDebugEnabled()) { logger.debug("No connection to the database. Exception: " + e.getMessage(), e); } throw new NoDBConnectionException("No connection to the database. Exception: ", e); } return user; }
/** {@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 Object createSavepoint() throws TransactionException { this.savepointCounter++; String savepointName = ConnectionHolder.SAVEPOINT_NAME_PREFIX + this.savepointCounter; try { Savepoint sp=this.entityManager.setSavepoint(savepointName); return sp; } catch (SavepointNotSupportedException e) { throw new NestedTransactionNotSupportedException("Cannot create a nested transaction because savepoints are not supported."); } catch (Throwable ex) { throw new CannotCreateTransactionException("Could not create JDBC savepoint", ex); } }
/** * Simulate a transaction infrastructure failure. * Shouldn't invoke target method. */ public void testCannotCreateTransaction() throws Exception { TransactionAttribute txatt = new DefaultTransactionAttribute(); Method m = getNameMethod; MapTransactionAttributeSource tas = new MapTransactionAttributeSource(); tas.register(m, txatt); PlatformTransactionManager ptm = mock(PlatformTransactionManager.class); // Expect a transaction CannotCreateTransactionException ex = new CannotCreateTransactionException("foobar", null); given(ptm.getTransaction(txatt)).willThrow(ex); TestBean tb = new TestBean() { @Override public String getName() { throw new UnsupportedOperationException( "Shouldn't have invoked target method when couldn't create transaction for transactional method"); } }; ITestBean itb = (ITestBean) advised(tb, ptm, tas); try { itb.getName(); fail("Shouldn't have invoked method"); } catch (CannotCreateTransactionException thrown) { assertTrue(thrown == ex); } }
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 public TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException { TransactionStatus status = super.getTransaction(definition); try { TransactionResourceManager.initSynchronization(); triggerBegin(status); } catch (Throwable e) { throw new CannotCreateTransactionException( "Unable to open the transaction", e); } return status; }
/** * This implementation sets the isolation level but ignores the timeout. */ @Override protected void doBegin(Object transaction, TransactionDefinition definition) { super.doBegin(transaction, definition); try { TransactionResourceManager.initSynchronization(); triggerBegin(); } catch (Throwable e) { throw new CannotCreateTransactionException( "Unable to begin the transaction", e); } }
public static void doBegin(Connection con, DataSource dataSource) { try { if (con.getAutoCommit()) { if (logger.isDebugEnabled()) { logger.debug("Switching JDBC Connection [" + con + "] to manual commit"); } con.setAutoCommit(false); } } catch (Throwable ex) { DataSourceUtils.releaseConnection(con); throw new CannotCreateTransactionException("Could not open JDBC Connection for transaction", ex); } }
public void doBegin(Object transaction, TransactionDefinition definition) throws TransactionException { try { CompensatingTransactionObject txObject = (CompensatingTransactionObject) transaction; if (txObject.getHolder() == null) { CompensatingTransactionHolderSupport contextHolder = getNewHolder(); txObject.setHolder(contextHolder); TransactionSynchronizationManager.bindResource(getTransactionSynchronizationKey(), contextHolder); } } catch (Exception e) { throw new CannotCreateTransactionException("Could not create DirContext instance for transaction", e); } }
protected void doBegin(Object arg0, TransactionDefinition arg1) { throw new CannotCreateTransactionException("Test exception."); }
/** * This implementation sets the isolation level but ignores the timeout. */ @Override protected void doBegin(Object transaction, TransactionDefinition definition) { DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction; Connection con = null; try { if (txObject.getConnectionHolder() == null || txObject.getConnectionHolder().isSynchronizedWithTransaction()) { Connection newCon = this.dataSource.getConnection(); if (logger.isDebugEnabled()) { logger.debug("Acquired Connection [" + newCon + "] for JDBC transaction"); } txObject.setConnectionHolder(new ConnectionHolder(newCon), true); } txObject.getConnectionHolder().setSynchronizedWithTransaction(true); con = txObject.getConnectionHolder().getConnection(); Integer previousIsolationLevel = DataSourceUtils.prepareConnectionForTransaction(con, definition); txObject.setPreviousIsolationLevel(previousIsolationLevel); // Switch to manual commit if necessary. This is very expensive in some JDBC drivers, // so we don't want to do it unnecessarily (for example if we've explicitly // configured the connection pool to set it already). if (con.getAutoCommit()) { txObject.setMustRestoreAutoCommit(true); if (logger.isDebugEnabled()) { logger.debug("Switching JDBC Connection [" + con + "] to manual commit"); } con.setAutoCommit(false); } txObject.getConnectionHolder().setTransactionActive(true); int timeout = determineTimeout(definition); if (timeout != TransactionDefinition.TIMEOUT_DEFAULT) { txObject.getConnectionHolder().setTimeoutInSeconds(timeout); } // Bind the session holder to the thread. if (txObject.isNewConnectionHolder()) { TransactionSynchronizationManager.bindResource(getDataSource(), txObject.getConnectionHolder()); } } catch (Throwable ex) { DataSourceUtils.releaseConnection(con, this.dataSource); throw new CannotCreateTransactionException("Could not open JDBC Connection for transaction", ex); } }
@Override public Response toResponse(final CannotCreateTransactionException exception) { log.error("Transaction exception", exception); return super.toResponse(); }
@DELETE @Path("transaction-begin") public void throwTransaction() { throw new CannotCreateTransactionException("message"); }
@DELETE @Path("transaction-begin2") public void throwTransaction2() { throw new CannotCreateTransactionException("message", new IOException("messageio")); }
@Test public void toResponse() { final CannotCreateTransactionException exception = new CannotCreateTransactionException("message-error"); check(mock(new CannotCreateTransactionExceptionMapper()).toResponse(exception), 503, "{\"code\":\"database-down\",\"message\":null,\"parameters\":null,\"cause\":null}"); }
@Test public void testTransactionCommitWithNonExistingDatabase() throws Exception { final DriverManagerDataSource ds = new DriverManagerDataSource(); LocalSessionFactoryBean lsfb = new LocalSessionFactoryBean(); lsfb.setDataSource(ds); Properties props = new Properties(); props.setProperty("hibernate.dialect", HSQLDialect.class.getName()); props.setProperty("hibernate.cache.provider_class", NoCacheProvider.class.getName()); lsfb.setHibernateProperties(props); lsfb.afterPropertiesSet(); final SessionFactory sf = lsfb.getObject(); HibernateTransactionManager tm = new HibernateTransactionManager(); tm.setSessionFactory(sf); tm.afterPropertiesSet(); TransactionTemplate tt = new TransactionTemplate(tm); tt.setIsolationLevel(TransactionDefinition.ISOLATION_SERIALIZABLE); tt.setTimeout(10); assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds)); assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive()); try { tt.execute(new TransactionCallback() { @Override public Object doInTransaction(TransactionStatus status) { assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf)); assertTrue("Has thread connection", TransactionSynchronizationManager.hasResource(ds)); HibernateTemplate ht = new HibernateTemplate(sf); return ht.find("from java.lang.Object"); } }); fail("Should have thrown CannotCreateTransactionException"); } catch (CannotCreateTransactionException ex) { // expected } assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds)); assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive()); }
@Test public void testTransactionCommitWithPreBoundSessionAndNonExistingDatabase() throws Exception { final DriverManagerDataSource ds = new DriverManagerDataSource(); LocalSessionFactoryBean lsfb = new LocalSessionFactoryBean(); lsfb.setDataSource(ds); Properties props = new Properties(); props.setProperty("hibernate.dialect", HSQLDialect.class.getName()); props.setProperty("hibernate.cache.provider_class", NoCacheProvider.class.getName()); lsfb.setHibernateProperties(props); lsfb.afterPropertiesSet(); final SessionFactory sf = lsfb.getObject(); HibernateTransactionManager tm = new HibernateTransactionManager(); tm.setSessionFactory(sf); tm.afterPropertiesSet(); TransactionTemplate tt = new TransactionTemplate(tm); tt.setIsolationLevel(TransactionDefinition.ISOLATION_SERIALIZABLE); tt.setTimeout(10); assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds)); assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive()); Session session = sf.openSession(); TransactionSynchronizationManager.bindResource(sf, new SessionHolder(session)); try { tt.execute(new TransactionCallback() { @Override public Object doInTransaction(TransactionStatus status) { assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf)); assertTrue("Has thread connection", TransactionSynchronizationManager.hasResource(ds)); HibernateTemplate ht = new HibernateTemplate(sf); return ht.find("from java.lang.Object"); } }); fail("Should have thrown CannotCreateTransactionException"); } catch (CannotCreateTransactionException ex) { // expected SessionHolder holder = (SessionHolder) TransactionSynchronizationManager.getResource(sf); assertFalse(holder.isSynchronizedWithTransaction()); } finally { TransactionSynchronizationManager.unbindResource(sf); session.close(); } assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds)); assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive()); }
/** * This implementation sets the isolation level but ignores the timeout. */ @Override protected void doBegin(Object transaction, TransactionDefinition definition) { DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction; Connection con = null; try { if (txObject.getConnectionHolder() == null || txObject.getConnectionHolder().isSynchronizedWithTransaction()) { Connection newCon = this.dataSource.getConnection(); if (logger.isDebugEnabled()) { logger.debug("Acquired Connection [" + newCon + "] for JDBC transaction"); } txObject.setConnectionHolder(new ConnectionHolder(newCon), true); } txObject.getConnectionHolder().setSynchronizedWithTransaction(true); con = txObject.getConnectionHolder().getConnection(); Integer previousIsolationLevel = DataSourceUtils.prepareConnectionForTransaction(con, definition); txObject.setPreviousIsolationLevel(previousIsolationLevel); // Switch to manual commit if necessary. This is very expensive in some JDBC drivers, // so we don't want to do it unnecessarily (for example if we've explicitly // configured the connection pool to set it already). if (con.getAutoCommit()) { txObject.setMustRestoreAutoCommit(true); if (logger.isDebugEnabled()) { logger.debug("Switching JDBC Connection [" + con + "] to manual commit"); } con.setAutoCommit(false); } txObject.getConnectionHolder().setTransactionActive(true); int timeout = determineTimeout(definition); if (timeout != TransactionDefinition.TIMEOUT_DEFAULT) { txObject.getConnectionHolder().setTimeoutInSeconds(timeout); } // Bind the session holder to the thread. if (txObject.isNewConnectionHolder()) { TransactionSynchronizationManager.bindResource(getDataSource(), txObject.getConnectionHolder()); } } catch (Throwable ex) { if (txObject.isNewConnectionHolder()) { DataSourceUtils.releaseConnection(con, this.dataSource); txObject.setConnectionHolder(null, false); } throw new CannotCreateTransactionException("Could not open JDBC Connection for transaction", ex); } }
@Test public void testTransactionCommitWithNonExistingDatabase() throws Exception { final DriverManagerDataSource ds = new DriverManagerDataSource(); LocalSessionFactoryBean lsfb = new LocalSessionFactoryBean(); lsfb.setDataSource(ds); Properties props = new Properties(); props.setProperty("hibernate.dialect", HSQLDialect.class.getName()); lsfb.setHibernateProperties(props); lsfb.afterPropertiesSet(); final SessionFactory sf = lsfb.getObject(); HibernateTransactionManager tm = new HibernateTransactionManager(); tm.setSessionFactory(sf); tm.afterPropertiesSet(); TransactionTemplate tt = new TransactionTemplate(tm); tt.setIsolationLevel(TransactionDefinition.ISOLATION_SERIALIZABLE); tt.setTimeout(10); assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds)); assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive()); try { tt.execute(new TransactionCallback() { @Override public Object doInTransaction(TransactionStatus status) { assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf)); assertTrue("Has thread connection", TransactionSynchronizationManager.hasResource(ds)); Session session = ((SessionHolder) TransactionSynchronizationManager.getResource(sf)).getSession(); return session.createQuery("from java.lang.Object").list(); } }); fail("Should have thrown CannotCreateTransactionException"); } catch (CannotCreateTransactionException ex) { // expected } assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds)); assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive()); }
@Override protected void doBegin(Object transaction, TransactionDefinition definition) { GuzzTransactionObject txObject = (GuzzTransactionObject) transaction; //TODO: checkout the outside DataSourceTransactionManager // if (txObject.hasConnectionHolder() && !txObject.getConnectionHolder().isSynchronizedWithTransaction()) { // throw new IllegalTransactionStateException( // "Pre-bound JDBC Connection found! GuzzTransactionManager does not support " + // "running within DataSourceTransactionManager if told to manage the DataSource itself. ") ; // } WriteTranSession writeTranSession = null ; try { if (txObject.getSessionHolder() == null || txObject.getSessionHolder().isSynchronizedWithTransaction()) { writeTranSession = getTransactionManager().openRWTran(false) ; if (logger.isDebugEnabled()) { logger.debug("Opened new Session [" + TransactionManagerUtils.toString(writeTranSession) + "] for Guzz transaction"); } txObject.setWriteTranSession(writeTranSession); } writeTranSession = txObject.getSessionHolder().getWriteTranSession() ; if (definition.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT) { // We should set a specific isolation level but are not allowed to... IsolationsSavePointer oldSavePointer = writeTranSession.setTransactionIsolation(definition.getIsolationLevel()) ; txObject.setIsolationsSavePointer(oldSavePointer) ; } // Register transaction timeout. int timeout = determineTimeout(definition); if (timeout != TransactionDefinition.TIMEOUT_DEFAULT) { txObject.getSessionHolder().setTimeoutInSeconds(timeout); } // Bind the session holder to the thread. if (txObject.isNewWriteTranSessionHolder()) { TransactionSynchronizationManager.bindResource(getTransactionManager(), txObject.getSessionHolder()); } txObject.getSessionHolder().setSynchronizedWithTransaction(true); }catch (Exception ex) { if (txObject.isNewWriteTranSession()) { try { if (writeTranSession != null) { //TransactionIsolation不需要重置,因为数据库连接还没有打开,没有连接因此而改变属性。 writeTranSession.rollback(); } } catch (Throwable ex2) { logger.debug("Could not rollback WriteTranSession after failed transaction begin", ex); } finally { TransactionManagerUtils.closeSession(writeTranSession); } } throw new CannotCreateTransactionException("Could not open Guzz WriteTranSession for transaction", ex); } }