| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #include <geode/Cache.hpp> |
| #include <geode/CacheTransactionManager.hpp> |
| |
| #include "TXState.hpp" |
| #include "TransactionalOperation.hpp" |
| #include "TssConnectionWrapper.hpp" |
| #include "ThinClientPoolDM.hpp" |
| #include "util/exception.hpp" |
| |
| namespace apache { |
| namespace geode { |
| namespace client { |
| |
| TXState::TXState(CacheImpl* cacheImpl) { |
| m_txId = TXId(); |
| m_closed = false; |
| m_modSerialNum = 0; |
| m_dirty = false; |
| m_replay = false; |
| m_prepared = false; |
| m_cache = cacheImpl; |
| /* adongre |
| * Non-static class member "m_suspendedExpiryTaskId" is not initialized in |
| * this constructor nor in any functions that it calls. |
| */ |
| m_suspendedExpiryTaskId = 0; |
| m_pooldm = nullptr; |
| } |
| |
| TXState::~TXState() {} |
| TXId& TXState::getTransactionId() { return m_txId; } |
| |
| int32_t TXState::nextModSerialNum() { |
| m_modSerialNum += 1; |
| return m_modSerialNum; |
| } |
| std::shared_ptr<Cacheable> TXState::replay(bool isRollback) { |
| GfErrTypeThrowException("Replay is unsupported", GF_NOTSUP); |
| int retryAttempts = 3; |
| |
| std::shared_ptr<Cacheable> result = nullptr; |
| |
| ReplayControl replayControl(this); |
| m_dirty = false; |
| // if retryAttempts < 0 we retry until there are no servers available |
| for (int i = 0; (retryAttempts < 0) || (i < retryAttempts); i++) { |
| // try { |
| if (isRollback) { // need to roll back these |
| try { |
| m_cache->getCacheTransactionManager() |
| ->rollback(); // this.firstProxy.rollback(proxy.getTxId().getUniqId()); |
| } catch (const Exception& ex) { |
| LOGFINE( |
| "caught exception when rolling back before retrying transaction " |
| "%s", |
| ex.what()); |
| } |
| } |
| m_txId = TXId(); |
| // LOGFINE("retrying transaction after loss of state in server. Attempt #" |
| // + (i+1)); |
| try { |
| for (const auto& operation : m_operations) { |
| result = operation->replay(m_cache); |
| } |
| |
| return result; |
| } catch (const TransactionDataNodeHasDepartedException& ex) { |
| LOGDEBUG("Transaction exception:%s", ex.what()); |
| isRollback = false; |
| // try again |
| } catch (const TransactionDataRebalancedException& ex) { |
| LOGDEBUG("Transaction exception:%s", ex.what()); |
| isRollback = true; |
| // try again |
| } |
| } |
| |
| GfErrTypeThrowException( |
| "Unable to reestablish transaction context on servers", GF_EUNDEF); |
| |
| return nullptr; |
| } |
| |
| void TXState::releaseStickyConnection() { |
| // Since this is called during cleanup or through destructor, we should not |
| // throw exception from here, |
| // which can cause undefined cleanup. |
| TcrConnection* conn = |
| (*TssConnectionWrapper::s_geodeTSSConn)->getConnection(); |
| if (conn != nullptr) { |
| ThinClientPoolDM* dm = conn->getEndpointObject()->getPoolHADM(); |
| if (dm != nullptr) { |
| if (!dm->isSticky()) { |
| LOGFINE( |
| "Release the sticky connection associated with the transaction"); |
| dm->releaseThreadLocalConnection(); // this will release connection now |
| } else { |
| LOGFINE( |
| "Pool with sticky connection - don't Release the sticky connection " |
| "associated with the transaction"); |
| conn->setAndGetBeingUsed(false, false); // just release connection now |
| } |
| } |
| } |
| } |
| } // namespace client |
| } // namespace geode |
| } // namespace apache |