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

中间件编程

开发平台:

Java

  1. /*
  2.  * JBoss, Home of Professional Open Source
  3.  * Copyright 2008, 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. package org.jboss.blacktie.jatmibroker.jab;
  19. import java.util.Hashtable;
  20. import java.util.Properties;
  21. import org.apache.log4j.LogManager;
  22. import org.apache.log4j.Logger;
  23. import org.jboss.blacktie.jatmibroker.core.transport.OrbManagement;
  24. import org.jboss.blacktie.jatmibroker.core.util.ThreadActionData;
  25. import org.jboss.blacktie.jatmibroker.core.util.ThreadUtil;
  26. import org.omg.CORBA.ORBPackage.InvalidName;
  27. import org.omg.CosNaming.NamingContextPackage.CannotProceed;
  28. import org.omg.CosNaming.NamingContextPackage.NotFound;
  29. import org.omg.CosTransactions.Control;
  30. import org.omg.CosTransactions.Status;
  31. import org.omg.CosTransactions.Terminator;
  32. import org.omg.CosTransactions.TransactionFactory;
  33. import org.omg.CosTransactions.TransactionFactoryHelper;
  34. import org.omg.CosTransactions.Unavailable;
  35. import org.omg.PortableServer.POAManagerPackage.AdapterInactive;
  36. public class JABTransaction {
  37. private static final Logger log = LogManager
  38. .getLogger(JABTransaction.class);
  39. static TransactionFactory transactionFactory;
  40. private JABSession jabSession;
  41. private int timeout;
  42. protected Control control;
  43. private Terminator terminator;
  44. private Hashtable _childThreads;
  45. private boolean active = true;
  46. private OrbManagement orbManagement;
  47. public void finalize() throws Throwable {
  48. // TODO use ThreadActionData.purgeAction(this); not popAction
  49. ThreadActionData.popAction();
  50. super.finalize();
  51. }
  52. public JABTransaction(JABSession aJABSession, int aTimeout)
  53. throws TransactionException, NotFound, CannotProceed,
  54. org.omg.CosNaming.NamingContextPackage.InvalidName, InvalidName,
  55. AdapterInactive {
  56. log.debug("JABTransaction constructor");
  57. if (current() != null)
  58. throw new TransactionException(
  59. "Nested transactions are not supported");
  60. jabSession = aJABSession;
  61. timeout = aTimeout;
  62. control = null;
  63. terminator = null;
  64. Properties properties = jabSession.getJABSessionAttributes()
  65. .getProperties();
  66. orbManagement = new OrbManagement(properties, true);
  67. String toLookup = (String) properties.get("blacktie.trans.factoryid");
  68. org.omg.CORBA.Object aObject = orbManagement.getNamingContextExt()
  69. .resolve_str(toLookup);
  70. transactionFactory = TransactionFactoryHelper.narrow(aObject);
  71. log.debug(" creating Control");
  72. control = transactionFactory.create(timeout);
  73. ThreadActionData.pushAction(this);
  74. log.debug(" created Control " + control);
  75. setTerminator(control);
  76. }
  77. public JABTransaction(String controlIOR) throws JABException {
  78. JABSessionAttributes sessionAttrs = new JABSessionAttributes();
  79. JABTransaction curr = current();
  80. jabSession = new JABSession(sessionAttrs);
  81. timeout = -1;
  82. try {
  83. orbManagement = new OrbManagement(sessionAttrs.getProperties(),
  84. true);
  85. } catch (org.omg.CORBA.UserException cue) {
  86. throw new TransactionException(cue.getMessage(), cue);
  87. }
  88. org.omg.CORBA.Object obj = orbManagement.getOrb().string_to_object(
  89. controlIOR);
  90. if (curr != null) {
  91. log.debug("current() != null comparing IORs");
  92. String pIOR = curr.getControlIOR();
  93. org.omg.CORBA.Object pObj = orbManagement.getOrb()
  94. .string_to_object(pIOR);
  95. log.debug("pIOR=" + pIOR + " pObj=" + pObj);
  96. if (pObj != null && pObj._is_equivalent(obj)) {
  97. log.debug("Different IORs same object");
  98. ThreadActionData.popAction();
  99. } else {
  100. log.info("Different IORs and different object");
  101. throw new TransactionException(
  102. "Nested transactions are not supported");
  103. }
  104. }
  105. control = org.omg.CosTransactions.ControlHelper.narrow(obj);
  106. ThreadActionData.pushAction(this);
  107. setTerminator(control);
  108. }
  109. public Status getStatus() throws Unavailable {
  110. return control.get_coordinator().get_status();
  111. }
  112. public boolean equals(java.lang.Object obj) {
  113. if (obj instanceof JABTransaction) {
  114. JABTransaction other = (JABTransaction) obj;
  115. return control.equals(other.control);
  116. }
  117. return false;
  118. }
  119. public static void associateTx(String controlIOR)
  120. throws TransactionException {
  121. try {
  122. // TODO make sure this works in the AS and standalone
  123. org.jboss.blacktie.jatmibroker.core.transport.JtsTransactionImple
  124. .resume(controlIOR);
  125. } catch (Throwable t) {
  126. new TransactionException(controlIOR);
  127. }
  128. }
  129. private void setTerminator(Control c) throws TransactionException {
  130. try {
  131. terminator = control.get_terminator();
  132. log.debug("Terminator is " + terminator);
  133. } catch (Unavailable e) {
  134. throw new TransactionException("Could not get the terminator", e);
  135. }
  136. }
  137. public String getControlIOR() {
  138. return orbManagement.getOrb().object_to_string(control);
  139. }
  140. public static JABTransaction current() {
  141. log.trace("Getting current");
  142. return ThreadActionData.currentAction();
  143. }
  144. public Control getControl() {
  145. log.debug("JABTransaction getControl");
  146. return control;
  147. }
  148. public JABSession getSession() {
  149. log.debug("JABTransaction getSession");
  150. return jabSession;
  151. }
  152. public void commit() throws TransactionException {
  153. log.debug("JABTransaction commit");
  154. try {
  155. log.debug("calling commit");
  156. terminator.commit(true);
  157. active = false;
  158. ThreadActionData.popAction();
  159. log.debug("called commit on terminator");
  160. } catch (Exception e) {
  161. // TODO build an JABTransactionException hierarchy so we can perform
  162. // better
  163. // error reporting
  164. // presume abort and dissassociate the tx from the the current
  165. // thread
  166. active = false;
  167. ThreadActionData.popAction();
  168. throw new TransactionException("Could not commit the transaction: "
  169. + e.getMessage(), e);
  170. }
  171. }
  172. public void rollback() throws TransactionException {
  173. log.debug("JABTransaction rollback");
  174. try {
  175. terminator.rollback();
  176. active = false;
  177. ThreadActionData.popAction();
  178. log.debug("called rollback on terminator");
  179. } catch (Exception e) {
  180. // presume abort and dissassociate the tx from the the current
  181. // thread
  182. active = false;
  183. ThreadActionData.popAction();
  184. throw new TransactionException(
  185. "Could not rollback the transaction: " + e.getMessage(), e);
  186. }
  187. }
  188. public void rollback_only() throws TransactionException {
  189. log.debug("JABTransaction rollback_only");
  190. try {
  191. control.get_coordinator().rollback_only();
  192. log.debug("tx marked rollback only");
  193. } catch (Unavailable e) {
  194. throw new TransactionException(
  195. "Tx Manager unavailable for set rollback only", e);
  196. } catch (Exception e) {
  197. throw new TransactionException("Error setting rollback only", e);
  198. }
  199. }
  200. /**
  201.  * Add the specified thread to the list of threads associated with this
  202.  * transaction.
  203.  * 
  204.  * @return <code>true</code> if successful, <code>false</code> otherwise.
  205.  */
  206. public final boolean addChildThread(Thread t) {
  207. if (t == null)
  208. return false;
  209. synchronized (this) {
  210. // if (actionStatus <= ActionStatus.ABORTING)
  211. if (active) {
  212. if (_childThreads == null)
  213. _childThreads = new Hashtable();
  214. // TODO _childThreads.put(ThreadUtil.getThreadId(t), t); //
  215. // makes sure so we don't get duplicates
  216. return true;
  217. }
  218. }
  219. return false;
  220. }
  221. /**
  222.  * Remove a child thread. The current thread is removed.
  223.  * 
  224.  * @return <code>true</code> if successful, <code>false</code> otherwise.
  225.  */
  226. public final boolean removeChildThread() // current thread
  227. {
  228. return removeChildThread(ThreadUtil.getThreadId());
  229. }
  230. /**
  231.  * Remove the specified thread from the transaction.
  232.  * 
  233.  * @return <code>true</code> if successful, <code>false</code> otherwise.
  234.  */
  235. public final boolean removeChildThread(String threadId) {
  236. if (threadId == null)
  237. return false;
  238. synchronized (this) {
  239. if (_childThreads != null) {
  240. _childThreads.remove(threadId);
  241. return true;
  242. }
  243. }
  244. return false;
  245. }
  246. public final JABTransaction parent() {
  247. return null;
  248. }
  249. /**
  250.  * Suspend the transaction association from the invoking thread. When this
  251.  * operation returns, the thread will not be associated with a transaction.
  252.  * 
  253.  * @return a handle on the current JABTransaction (if any) so that the
  254.  *         thread can later resume association if required.
  255.  */
  256. public static final JABTransaction suspend() {
  257. JABTransaction curr = ThreadActionData.currentAction();
  258. if (curr != null)
  259. ThreadActionData.purgeActions();
  260. return curr;
  261. }
  262. /**
  263.  * Resume transaction association on the current thread. If the specified
  264.  * transaction is null, then this is the same as doing a suspend. If the
  265.  * current thread is associated with a transaction then that association
  266.  * will be lost.
  267.  * 
  268.  * @param JABTransaction
  269.  *            act the transaction to associate.
  270.  * @return <code>true</code> if association is successful,
  271.  *         <code>false</code> otherwise.
  272.  */
  273. public static final boolean resume(JABTransaction act) {
  274. if (act == null)
  275. suspend();
  276. else
  277. ThreadActionData.restoreActions(act);
  278. return true;
  279. }
  280. }