XAResourceAdaptorImpl.cxx
上传用户:xfwatch
上传日期:2020-12-14
资源大小:872k
文件大小:9k
源码类别:

中间件编程

开发平台:

Java

  1. /*
  2.  * JBoss, Home of Professional Open Source
  3.  * Copyright 2009, Red Hat, Inc., and others contributors as indicated
  4.  * by the @authors tag. All rights reserved.
  5.  * See the copyright.txt in the distribution for a
  6.  * full listing of individual contributors.
  7.  * This copyrighted material is made available to anyone wishing to use,
  8.  * modify, copy, or redistribute it subject to the terms and conditions
  9.  * of the GNU Lesser General Public License, v. 2.1.
  10.  * This program is distributed in the hope that it will be useful, but WITHOUT A
  11.  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
  12.  * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
  13.  * You should have received a copy of the GNU Lesser General Public License,
  14.  * v.2.1 along with this distribution; if not, write to the Free Software
  15.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
  16.  * MA  02110-1301, USA.
  17.  */
  18. #include "XAResourceAdaptorImpl.h"
  19. #include "ace/OS_NS_stdlib.h" /* TODO delete when done testing TEST_BLACKTIE_209 */
  20. log4cxx::LoggerPtr xaralogger(log4cxx::Logger::getLogger("TxLogXAAdaptor"));
  21. extern std::ostream& operator<<(std::ostream &os, const XID& xid);
  22. using namespace atmibroker::xa;
  23. XAResourceAdaptorImpl::XAResourceAdaptorImpl(
  24. XAResourceManager * rm, XID& xid, XID& bid, CORBA::Long rmid,
  25. struct xa_switch_t * xa_switch, XARecoveryLog& log) throw (RMException) :
  26. rm_(rm), xid_(xid), bid_(bid), complete_(false), rmid_(rmid), xa_switch_(xa_switch), rc_(0),
  27. eflags_(0l), tightly_coupled_(0), rclog_(log), prepared_(false)
  28. {
  29. FTRACE(xaralogger, "ENTER" << (char*) " new OTS resource rmid:" << rmid_ << " branch id: " << bid_);
  30. }
  31. XAResourceAdaptorImpl::~XAResourceAdaptorImpl()
  32. {
  33. FTRACE(xaralogger, "ENTER");
  34. if (rc_)
  35. free(rc_);
  36. }
  37. void XAResourceAdaptorImpl::notify_error(int reason, bool forget)
  38. {
  39. FTRACE(xaralogger, "ENTER");
  40. if (rm_)
  41. rm_->notify_error(&xid_, reason, forget);
  42. }
  43. void XAResourceAdaptorImpl::set_complete()
  44. {
  45. FTRACE(xaralogger, "ENTER");
  46. complete_ = true;
  47. if (rm_)
  48. rm_->set_complete(&xid_);
  49. }
  50. Vote XAResourceAdaptorImpl::prepare()
  51. throw (HeuristicMixed,HeuristicHazard)
  52. {
  53. FTRACE(xaralogger, "ENTER astate=" << sm_.astate() << " bstate=" << sm_.bstate());
  54. int rv1, rv2;
  55. // This resource is joining an existing branch. In this case the thread that
  56. // originally started the branch is responsible for all updates the RM.
  57. // Disable since we have introduced bid_ for unique branches for work
  58. // performed on the RM from different processes
  59. if (tightly_coupled_)
  60. return VoteReadOnly;
  61. rv1 = xa_end(TMSUCCESS);
  62. rv2 = xa_prepare(TMNOFLAGS);
  63. if (rv1 != XA_OK && rv2 == XA_OK) {
  64. LOG4CXX_DEBUG(xaralogger, (char*) "OTS resource: end TMSUCCESS was already set");
  65. }
  66. if (rv2 != XA_OK && rv2 != XA_RDONLY) {
  67. LOG4CXX_WARN(xaralogger, (char *) xa_switch_->name <<
  68. (char*) ": prepare OTS resource error: " << rv2 << " rid=" << rmid_ << (char*) " rv1=" << rv1);
  69. } else {
  70. LOG4CXX_DEBUG(xaralogger, (char*) "prepare OTS resource end ok: rid=" << rmid_
  71. << (char*) " rv1=" << rv1 << " rv2=" << rv2 << " bstate=" << sm_.bstate());
  72. }
  73. if (rc_ == NULL) {
  74. rv2 = XA_RDONLY;
  75. LOG4CXX_ERROR(xaralogger, (char *) "prepare called but no recovery coordinator has been set - assuming RDONLY");
  76. }
  77. if (rv2 == XA_OK) {
  78. #if TX_RC == 3
  79. if (ACE_OS::getenv("TEST_BLACKTIE_209")) {
  80. LOG4CXX_INFO(xaralogger, (char *) "Test BLACKTIE_209:- SEGV after prepare but before writing log");
  81. char *s = 0;
  82. *s = 0;
  83. }
  84. #endif
  85. // about to vote commit - remember the descision
  86. rclog_.add_rec(bid_, rc_);
  87. prepared_ = true;
  88. }
  89. switch (rv2) {
  90. case XA_OK:
  91. return VoteCommit;
  92. case XA_RDONLY:
  93. return VoteReadOnly;
  94. case XA_RBROLLBACK:
  95. case XA_RBCOMMFAIL:
  96. case XA_RBDEADLOCK:
  97. case XA_RBINTEGRITY:
  98. case XA_RBOTHER:
  99. case XA_RBPROTO:
  100. case XA_RBTIMEOUT:
  101. case XA_RBTRANSIENT:
  102. case XAER_ASYNC:
  103. case XAER_RMERR:
  104. case XAER_RMFAIL:
  105. case XAER_NOTA:
  106. case XAER_INVAL:
  107. case XAER_PROTO:
  108. return VoteRollback;
  109. default:  // shouldn't happen
  110. return VoteRollback;
  111. }
  112. }
  113. void XAResourceAdaptorImpl::terminate(int rv)
  114. throw(
  115. HeuristicRollback,
  116. HeuristicMixed,
  117. HeuristicHazard)
  118. {
  119. FTRACE(xaralogger, "ENTER");
  120. // remove the entry for this branch from the recovery log
  121. if (prepared_ && rclog_.del_rec(bid_) != 0) {
  122. LOG4CXX_DEBUG(xaralogger, (char *) xa_switch_->name <<
  123. ": terminate - entry not found in recovery log rid=" << rmid_);
  124. }
  125. switch (rv) {
  126. default:
  127. break;
  128. case XA_HEURHAZ: {
  129. HeuristicHazard e;
  130. notify_error(rv, true);
  131. throw e;
  132. break;
  133. }
  134. case XA_HEURCOM:
  135. // a heuristic descision to commit was made (we were lucky) 
  136. break;
  137. case XA_HEURRB:
  138. case XA_RBROLLBACK: // these codes may be returned only if the TMONEPHASE flag was set
  139. case XA_RBCOMMFAIL:
  140. case XA_RBDEADLOCK:
  141. case XA_RBINTEGRITY:
  142. case XA_RBOTHER:
  143. case XA_RBPROTO:
  144. case XA_RBTIMEOUT:
  145. case XA_RBTRANSIENT: {
  146. HeuristicRollback e;
  147. notify_error(rv, true);
  148. throw e;
  149. break;
  150. }
  151. case XA_HEURMIX: {
  152. HeuristicMixed e;
  153. notify_error(rv, true);
  154. throw e;
  155. break;
  156. }
  157. }
  158. }
  159. void XAResourceAdaptorImpl::commit()
  160. throw(
  161. NotPrepared,
  162. HeuristicRollback,
  163. HeuristicMixed,
  164. HeuristicHazard)
  165. {
  166. FTRACE(xaralogger, "ENTER");
  167. if (tightly_coupled_) {
  168. set_complete();
  169. return;
  170. }
  171. int rv = xa_commit (TMNOFLAGS); // no need for xa_end since prepare must have been called
  172. LOG4CXX_TRACE(xaralogger, (char*) "OTS resource commit rv=" << rv);
  173. terminate(rv);
  174. set_complete();
  175. }
  176. void XAResourceAdaptorImpl::rollback()
  177. throw(HeuristicCommit,HeuristicMixed,HeuristicHazard)
  178. {
  179. long eflags = eflags_;
  180. FTRACE(xaralogger, "ENTER");
  181. if (tightly_coupled_) {
  182. set_complete();
  183. return;
  184. }
  185. int rv = xa_end (TMSUCCESS);
  186. if (rv != XA_OK && eflags != TMSUCCESS) {
  187. LOG4CXX_WARN(xaralogger, (char *) xa_switch_->name <<
  188. (char*) ": rollback OTS resource end error " << rv <<
  189. " for rid " << rmid_ << " - flags=" << std::hex << eflags);
  190. } else {
  191. // if rv != XA_OK and the branch was already idle then log at debug only - see ch 6 of the XA spec
  192. LOG4CXX_DEBUG(xaralogger, (char *) xa_switch_->name <<
  193. (char*) ": rollback OTS resource end result " << rv <<
  194. " for rid " << rmid_ << " - flags=" << std::hex << eflags);
  195. }
  196. rv = xa_rollback (TMNOFLAGS);
  197. LOG4CXX_DEBUG(xaralogger, (char*) "OTS resource rollback rv=" << rv);
  198. terminate(rv);
  199. set_complete();
  200. }
  201. void XAResourceAdaptorImpl::commit_one_phase() throw(HeuristicHazard)
  202. {
  203. FTRACE(xaralogger, "ENTER");
  204. if (tightly_coupled_) {
  205. set_complete();
  206. return;
  207. }
  208. int rv = xa_end (TMSUCCESS);
  209. if (rv != XA_OK) {
  210. LOG4CXX_WARN(xaralogger, (char *) xa_switch_->name <<
  211. (char*) ": commit 1PC OTS resource end failed: error=" << rv << " rid=" << rmid_);
  212. } else {
  213. LOG4CXX_DEBUG(xaralogger, (char*) "1PC OTS resource end ok, rid=" << rmid_);
  214. }
  215. rv = xa_commit (TMONEPHASE);
  216. LOG4CXX_DEBUG(xaralogger, (char*) "1PC OTS resource commit rv=" << rv);
  217. terminate(rv);
  218. set_complete();
  219. }
  220. void XAResourceAdaptorImpl::forget()
  221. {
  222. FTRACE(xaralogger, "ENTER");
  223. int rv = xa_forget (TMNOFLAGS);
  224. LOG4CXX_TRACE(xaralogger, (char*) "OTS resource forget rv=" << rv);
  225. set_complete();
  226. }
  227. // accessors
  228. bool XAResourceAdaptorImpl::is_complete()
  229. {
  230. FTRACE(xaralogger, "ENTER");
  231. return complete_;
  232. }
  233. // XA methods
  234. int XAResourceAdaptorImpl::xa_start (long flags)
  235. {
  236. FTRACE(xaralogger, (char*) "ENTER astate=" << sm_.astate() << " bstate=" << sm_.bstate());
  237.  
  238. int rv = xa_switch_->xa_start_entry(&bid_, rmid_, flags);
  239. return sm_.transition(bid_, XACALL_START, flags, rv);
  240. }
  241. int XAResourceAdaptorImpl::xa_end (long flags)
  242. {
  243. FTRACE(xaralogger, (char*) "ENTER bstate=" << std::hex << sm_.bstate() << " flags=" << flags);
  244.  
  245. LOG4CXX_DEBUG(xaralogger, (char*) "XA_END rmid: " << rmid_ << std::hex << " flags: " << eflags_ << " -> " << flags);
  246. eflags_ = flags;
  247. // if the branch is already idle just return OK - see ch 6 of the XA specification
  248. // if (sm_.bstate() == S2)
  249. // return XA_OK;
  250. int rv = xa_switch_->xa_end_entry(&bid_, rmid_, flags);
  251. return sm_.transition(bid_, XACALL_END, flags, rv);
  252. }
  253. int XAResourceAdaptorImpl::xa_rollback (long flags)
  254. {
  255. FTRACE(xaralogger, (char*) "ENTER bstate=" << sm_.bstate());
  256. int rv = xa_switch_->xa_rollback_entry(&bid_, rmid_, flags);
  257. return sm_.transition(bid_, XACALL_ROLLBACK, flags, rv);
  258. }
  259. int XAResourceAdaptorImpl::xa_prepare (long flags)
  260. {
  261. FTRACE(xaralogger, (char*) "ENTER bstate=" << sm_.bstate());
  262. int rv = xa_switch_->xa_prepare_entry(&bid_, rmid_, flags);
  263. return sm_.transition(bid_, XACALL_PREPARE, flags, rv);
  264. }
  265. int XAResourceAdaptorImpl::xa_commit (long flags)
  266. {
  267. FTRACE(xaralogger, (char*) "ENTER bstate=" << sm_.bstate());
  268. LOG4CXX_DEBUG(xaralogger, (char*) "Commiting resource with branch id: " << bid_);
  269. int rv = xa_switch_->xa_commit_entry(&bid_, rmid_, flags);
  270. return sm_.transition(bid_, XACALL_COMMIT, flags, rv);
  271. }
  272. int XAResourceAdaptorImpl::xa_recover (long xxx, long flags)
  273. {
  274. FTRACE(xaralogger, (char*) "ENTER bstate=" << sm_.bstate());
  275. int rv = xa_switch_->xa_recover_entry(&bid_, xxx, rmid_, flags);
  276. return sm_.transition(bid_, XACALL_RECOVER, flags, rv);
  277. }
  278. int XAResourceAdaptorImpl::xa_forget (long flags)
  279. {
  280. FTRACE(xaralogger, (char*) "ENTER bstate=" << sm_.bstate());
  281. int rv = xa_switch_->xa_forget_entry(&bid_, rmid_, flags);
  282. return sm_.transition(bid_, XACALL_FORGET, flags, rv);
  283. }
  284. int XAResourceAdaptorImpl::xa_complete (int * handle, int * retvalue, long flags)
  285. {
  286. FTRACE(xaralogger, (char*) "ENTER");
  287. int rv = xa_switch_->xa_complete_entry(handle, retvalue, rmid_, flags);
  288. return rv;
  289. }