PageRenderTime 21ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 0ms

/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/PeerTXStateStub.java

https://gitlab.com/kidaa/incubator-geode
Java | 248 lines | 178 code | 26 blank | 44 comment | 29 complexity | b38a6838a0425c7b8da541a737f659ce MD5 | raw file
  1. /*=========================================================================
  2. * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
  3. * This product is protected by U.S. and international copyright
  4. * and intellectual property laws. Pivotal products are covered by
  5. * one or more patents listed at http://www.pivotal.io/patents.
  6. *=========================================================================
  7. */
  8. package com.gemstone.gemfire.internal.cache;
  9. import org.apache.logging.log4j.Logger;
  10. import com.gemstone.gemfire.CancelException;
  11. import com.gemstone.gemfire.cache.CommitConflictException;
  12. import com.gemstone.gemfire.cache.TransactionDataRebalancedException;
  13. import com.gemstone.gemfire.cache.TransactionException;
  14. import com.gemstone.gemfire.cache.TransactionInDoubtException;
  15. import com.gemstone.gemfire.cache.client.internal.ServerRegionDataAccess;
  16. import com.gemstone.gemfire.distributed.DistributedMember;
  17. import com.gemstone.gemfire.distributed.internal.ReliableReplyException;
  18. import com.gemstone.gemfire.distributed.internal.ReliableReplyProcessor21;
  19. import com.gemstone.gemfire.distributed.internal.ReplyException;
  20. import com.gemstone.gemfire.distributed.internal.membership.InternalDistributedMember;
  21. import com.gemstone.gemfire.internal.cache.TXRemoteCommitMessage.RemoteCommitResponse;
  22. import com.gemstone.gemfire.internal.cache.tx.DistributedTXRegionStub;
  23. import com.gemstone.gemfire.internal.cache.tx.PartitionedTXRegionStub;
  24. import com.gemstone.gemfire.internal.cache.tx.TXRegionStub;
  25. import com.gemstone.gemfire.internal.cache.tx.TransactionalOperation.ServerRegionOperation;
  26. import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
  27. import com.gemstone.gemfire.internal.logging.LogService;
  28. public class PeerTXStateStub extends TXStateStub {
  29. protected static final Logger logger = LogService.getLogger();
  30. private InternalDistributedMember originatingMember = null;
  31. protected TXCommitMessage commitMessage = null;
  32. public PeerTXStateStub(TXStateProxy stateProxy, DistributedMember target,InternalDistributedMember onBehalfOfClient) {
  33. super(stateProxy, target);
  34. this.originatingMember = onBehalfOfClient;
  35. }
  36. /* (non-Javadoc)
  37. * @see com.gemstone.gemfire.internal.cache.TXStateInterface#rollback()
  38. */
  39. @Override
  40. public void rollback() {
  41. /*
  42. * txtodo: work this into client realm
  43. */
  44. ReliableReplyProcessor21 response = TXRemoteRollbackMessage.send(
  45. this.proxy.getCache(),
  46. this.proxy.getTxId().getUniqId(),
  47. getOriginatingMember(),
  48. this.target);
  49. if (this.internalAfterSendRollback != null) {
  50. this.internalAfterSendRollback.run();
  51. }
  52. try {
  53. response.waitForReplies();
  54. } catch(PrimaryBucketException pbe) {
  55. // ignore this
  56. } catch (ReplyException e) {
  57. this.proxy.getCache().getCancelCriterion().checkCancelInProgress(e);
  58. if (e.getCause() != null && e.getCause() instanceof CancelException) {
  59. // other cache must have closed (bug #43649), so the transaction is lost
  60. if (this.internalAfterSendRollback != null) {
  61. this.internalAfterSendRollback.run();
  62. }
  63. } else {
  64. throw new TransactionException(LocalizedStrings.
  65. TXStateStub_ROLLBACK_ON_NODE_0_FAILED.toLocalizedString(target), e);
  66. }
  67. } catch(Exception e) {
  68. this.getCache().getCancelCriterion().checkCancelInProgress(e);
  69. throw new TransactionException(LocalizedStrings.
  70. TXStateStub_ROLLBACK_ON_NODE_0_FAILED.toLocalizedString(target), e);
  71. } finally {
  72. cleanup();
  73. }
  74. }
  75. @Override
  76. public void commit() throws CommitConflictException {
  77. assert target != null;
  78. /*
  79. * txtodo: Going to need to deal with client here
  80. */
  81. RemoteCommitResponse message =
  82. TXRemoteCommitMessage.send(this.proxy.getCache(),
  83. this.proxy.getTxId().getUniqId(),
  84. this.getOriginatingMember(),
  85. target);
  86. if (this.internalAfterSendCommit != null) {
  87. this.internalAfterSendCommit.run();
  88. }
  89. try {
  90. commitMessage = message.waitForResponse();
  91. } catch (CommitConflictException e) {
  92. throw e;
  93. } catch(TransactionException te) {
  94. throw te;
  95. } catch (ReliableReplyException e) {
  96. if(e.getCause()!=null) {
  97. throw new TransactionInDoubtException(e.getCause());
  98. } else {
  99. throw new TransactionInDoubtException(e);
  100. }
  101. } catch(ReplyException e) {
  102. if(e.getCause() instanceof CommitConflictException) {
  103. throw (CommitConflictException)e.getCause();
  104. } else if(e.getCause() instanceof TransactionException) {
  105. throw (TransactionException)e.getCause();
  106. }
  107. /*
  108. if(e.getCause()!=null) {
  109. throw new CommitConflictException(e.getCause());
  110. } else {
  111. throw new CommitConflictException(e);
  112. } */
  113. if(e.getCause()!=null) {
  114. throw new TransactionInDoubtException(e.getCause());
  115. } else {
  116. throw new TransactionInDoubtException(e);
  117. }
  118. } catch (Exception e) {
  119. this.getCache().getCancelCriterion().checkCancelInProgress(e);
  120. if (e.getCause()!=null) {
  121. if (e.getCause() instanceof ForceReattemptException) {
  122. Throwable e2 = e.getCause();
  123. if (e2.getCause()!=null && e2.getCause() instanceof PrimaryBucketException) {
  124. // data rebalanced
  125. TransactionDataRebalancedException tdnce = new TransactionDataRebalancedException(e2.getCause().getMessage());
  126. tdnce.initCause(e2.getCause());
  127. throw tdnce;
  128. } else {
  129. // We cannot be sure that the member departed starting to process commit request,
  130. // so throw a TransactionInDoubtException rather than a TransactionDataNodeHasDeparted. fixes 44939
  131. TransactionInDoubtException tdnce = new TransactionInDoubtException(e.getCause().getMessage());
  132. tdnce.initCause(e.getCause());
  133. throw tdnce;
  134. }
  135. }
  136. throw new TransactionInDoubtException(e.getCause());
  137. } else {
  138. throw new TransactionInDoubtException(e);
  139. }
  140. } finally {
  141. cleanup();
  142. }
  143. }
  144. protected void cleanup() {
  145. for (TXRegionStub regionStub : regionStubs.values()) {
  146. regionStub.cleanup();
  147. }
  148. }
  149. @Override
  150. protected TXRegionStub generateRegionStub(LocalRegion region) {
  151. TXRegionStub stub = null;
  152. if(region.getPartitionAttributes()==null) {
  153. // This is a dist region
  154. stub = new DistributedTXRegionStub(this,region);
  155. } else {
  156. stub = new PartitionedTXRegionStub(this,region);
  157. }
  158. return stub;
  159. }
  160. @Override
  161. protected void validateRegionCanJoinTransaction(LocalRegion region)
  162. throws TransactionException {
  163. /*
  164. * Ok is this region legit to enter into tx?
  165. */
  166. if(region.hasServerProxy()) {
  167. /*
  168. * This is a c/s region in a peer tx. nope!
  169. */
  170. throw new TransactionException("Can't involve c/s region in peer tx");
  171. }
  172. }
  173. @Override
  174. public void afterCompletion(int status) {
  175. RemoteCommitResponse response = JtaAfterCompletionMessage.send(this.proxy.getCache(),
  176. this.proxy.getTxId().getUniqId(),getOriginatingMember(), status, this.target);
  177. try {
  178. this.proxy.getTxMgr().setTXState(null);
  179. this.commitMessage = response.waitForResponse();
  180. if (logger.isDebugEnabled()) {
  181. logger.debug("afterCompletion received commit response of {}", this.commitMessage);
  182. }
  183. } catch (Exception e) {
  184. throw new TransactionException(e);
  185. //TODO throw a better exception
  186. } finally {
  187. cleanup();
  188. }
  189. }
  190. public InternalDistributedMember getOriginatingMember() {
  191. /*
  192. * This needs to be set to the clients member id if the client originated the tx
  193. */
  194. return originatingMember;
  195. }
  196. public void setOriginatingMember(InternalDistributedMember clientMemberId) {
  197. /*
  198. * This TX is on behalf of a client, so we have to send the client's member id around
  199. */
  200. this.originatingMember = clientMemberId;
  201. }
  202. @Override
  203. public boolean isMemberIdForwardingRequired() {
  204. return getOriginatingMember()!=null;
  205. }
  206. @Override
  207. public TXCommitMessage getCommitMessage() {
  208. return commitMessage;
  209. }
  210. @Override
  211. public void suspend() {
  212. // no special tasks to perform
  213. }
  214. @Override
  215. public void resume() {
  216. // no special tasks to perform
  217. }
  218. @Override
  219. public void recordTXOperation(ServerRegionDataAccess region, ServerRegionOperation op, Object key, Object arguments[]) {
  220. // no-op here
  221. }
  222. }