summaryrefslogtreecommitdiffstats
path: root/site/trunk/site-publish/transaction-intents-and-transaction-manager-support.html
diff options
context:
space:
mode:
Diffstat (limited to 'site/trunk/site-publish/transaction-intents-and-transaction-manager-support.html')
-rw-r--r--site/trunk/site-publish/transaction-intents-and-transaction-manager-support.html264
1 files changed, 264 insertions, 0 deletions
diff --git a/site/trunk/site-publish/transaction-intents-and-transaction-manager-support.html b/site/trunk/site-publish/transaction-intents-and-transaction-manager-support.html
new file mode 100644
index 0000000000..36ffddcc69
--- /dev/null
+++ b/site/trunk/site-publish/transaction-intents-and-transaction-manager-support.html
@@ -0,0 +1,264 @@
+
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<HTML>
+ <HEAD>
+ <LINK type="text/css" rel="stylesheet" href="http://incubator.apache.org/tuscany/stylesheets/default.css">
+ <LINK rel="SHORTCUT ICON" href="http://cwiki.apache.org/confluence/display/TUSCANY/$images/favicon.ico">
+ <TITLE>Transaction Intents and Transaction Manager support : Apache Tuscany</TITLE>
+ <META http-equiv="Content-Type" content="text/html;charset=UTF-8"></HEAD>
+
+ <BODY onload="init()">
+
+ <TABLE valign="top" border="0" cellspacing="0" cellpadding="0" width="100%" background="http://incubator.apache.org/tuscany/images/TuscanyLogoNEW_Text_120px_bg.jpg">
+ <TR>
+ <TD valing="top" align="left">
+ <A href="http://cwiki.apache.org/confluence/pages/viewpage.action?spaceKey=TUSCANY&title=$siteroot"><IMG src="http://incubator.apache.org/tuscany/images/TuscanyLogoNEW_Text_120px_bg.jpg" height="91" width="25" border="0"></A>
+ </TD>
+ <TD>
+ <A href="http://incubator.apache.org/tuscany/"><IMG src="http://incubator.apache.org/tuscany/images/TuscanyLogo.jpg" border="0"></A>
+ </TD>
+
+ <TD width="100%">
+ &nbsp;
+ </TD>
+ <TD align="right">
+ <IMG src="http://incubator.apache.org/tuscany/images/apache-incubator-logo.png" border="0">
+ </TD>
+
+ <!-- Adds the edit page link to the top banner-->
+ <TD valign="bottom">
+ <DIV style="padding: 2px 10px; margin: 0px;">
+ <A href="http://cwiki.apache.org/confluence/pages/editpage.action?pageId=67710">
+ <IMG src="http://incubator.apache.org/tuscany/images/notep_16.gif" height="16" width="16" border="0" align="absmiddle" title="Edit Page"></A>
+ </DIV>
+ </TD>
+
+ </TR>
+ </TABLE>
+
+ <TABLE border="0" cellpadding="2" cellspacing="0" width="100%">
+ <TR class="topBar">
+ <TD align="left" valign="middle" class="topBarDiv" nowrap="true" width="100%">
+ &nbsp;<A href="home.html" title="Apache Tuscany">Apache Tuscany</A>&nbsp;&gt;&nbsp;<A href="home.html" title="Home">Home</A>&nbsp;&gt;&nbsp;<A href="menus.html" title="Menus">Menus</A>&nbsp;&gt;&nbsp;<A href="subproject-menus.html" title="Subproject Menus">Subproject Menus</A>&nbsp;&gt;&nbsp;<A href="das-java-subproject-menu.html" title="DAS Java Subproject Menu">DAS Java Subproject Menu</A>&nbsp;&gt;&nbsp;<A href="design-discussions.html" title="Design Discussions">Design Discussions</A>&nbsp;&gt;&nbsp;<A href="" title="Transaction Intents and Transaction Manager support">Transaction Intents and Transaction Manager support</A>
+ </TD>
+
+ <TD align="left" valign="middle" class="topBarDiv" nowrap="true">
+ <A href="http://mail-archives.apache.org/mod_mbox/ws-tuscany-user">User List</A> | <A href="http://mail-archives.apache.org/mod_mbox/ws-tuscany-dev">Dev List</A> | <A href="http://issues.apache.org/jira/browse/Tuscany">Issue Tracker</A>&nbsp;&nbsp;
+ </TD>
+ </TR>
+ </TABLE>
+
+ <TABLE border="0" cellpadding="0" width="100%" bgcolor="#FFFFFF">
+ <TR>
+ <TD align="left" valign="top">
+ <DIV id="PageContent">
+
+ <DIV class="pagecontent">
+ <DIV class="wiki-content">
+ <P>As this topic involves a lot of discussion thought the better place will be wiki.</P>
+
+<P>I was just thinking randomly to see how to integrate the work in JIRA-1816 with the work<BR>
+in JIRA-1700(implementation.das support for tx inents/policies). Below are some suggestions I could gather,<BR>
+but need lot of feedback and ideas.</P>
+
+<H3><A name="TransactionIntentsandTransactionManagersupport-TransactionManagersupportinSCA%28JIRA1816%29"></A>TransactionManager support in SCA (JIRA-1816)</H3>
+<P>---------------------------------------------------------------------------------------------------------------------------------<BR>
+TransactionInfo - can have 2 subclasses - GlobalTransactionInfo (XADataSource...), LocalTransactionInfo (Connection...)<BR>
+we can rename TransactionInfo to TransactionContext if it suits.</P>
+
+<P>TransactionManager - also can have 2 similar flavours - LocalTransactionManager (what is there in the transaction.zip today)<BR>
+and GlobalTransactionManager. GlobalTransactionManager can support say a class level annotation - @TransactionManagerFactory(Geronimo)<BR>
+to have a way to inject an externally available TransactionManager like Geronimo, JOTM etc.<BR>
+---------------------------------------------------------------------------------------------------------------------------------</P>
+
+<H3><A name="TransactionIntentsandTransactionManagersupport-TxPolicySupportinimplementation.das%28JIRA1700%29"></A>Tx Policy Support in implementation.das (JIRA-1700)</H3>
+
+<P>----------------------------------------------------------------------------------------------------------------------------------------------<BR>
+I went through the Tx Policy Draft and trying to understand it in detail. Below trying to give examples of different scenarions<BR>
+for implementation.das and attempting to analyze just some part from that. Getting lost in different places <IMG class="emoticon" src="http://cwiki.apache.org/confluence/images/icons/emoticons/smile.gif" height="20" width="20" align="absmiddle" alt="" border="0">. Need all possible comments.<BR>
+I am just gathering all points below, with some discussions can prepare a design doc if that helps.</P>
+
+<P>(RM=Resource Manager) (xads = XADataSource) (xares=XAResource)(conn=connection)(2PC - 2 Phase Commit)<BR>
+----------------------------------------------------------------------------------------------------------------------------------------------<BR>
+Note: <BR>
+a&gt; It is possible that the caller (say junit test case) passes XADataSource(which has Connection and XAResource) OR same can be obtained from <BR>
+within SCA runtime.<BR>
+b&gt; At das.implementation level intents can be - managedTransaction.global, managedTransaction.local, noManagedTransaction, (still not clear why to support unqualified managedTransaction)<BR>
+c&gt; At present, implementation.das does not support oneWayInvocation - so need not consider transactedOneWay and immediateOneWay - is this right assumption?<BR>
+d&gt; At service level intents can be - propagatesTransaction, suspendsTransaction<BR>
+----------------------------------------------------------------------------------------------------------------------------------------------<BR>
+Scenarios:- </P>
+
+<P><B>CASE1) 1 component - 1 impl - 1 connection info - multiple services - multiple operations/service</B></P>
+
+<P>so at the time of createInvoker() for a service, the SCArutime can know both the intents (impl and interaction) and decide how to act on it.<BR>
+i.e. during DASImplementationProvider.createInvoker().</P>
+
+<P>1 impl == 1 RM (multiple Connections/XAConnections). <BR>
+so multiple services in the same .composite will use the same RM</P>
+
+<P>In DASImplementationProvider(component, impl) we have DASImplementationProvider.createInvoker(service, operation)<BR>
+One DASImplementationProvider has 1 DataAccessEngineManager. Bue each createInvoker() has a new DASInvoker() with new das<BR>
+and new DataAccessEngine. So each new invoker() will have a diff das instance.</P>
+
+<P><B>example</B></P>
+
+<P>scaDomain = SCADomain.newInstance(&quot;company.composite&quot;);<BR>
+dasCompanyService = scaDomain.getService(CompanyService.class, &quot;CompanyComponent/CompanyServiceComponent&quot;);</P>
+
+<P>dasCustomerService = scaDomain.getService(CustomerService.class, &quot;CompanyComponent/CustomerServiceComponent&quot;);</P>
+
+<P>dasCompanyService.updateCompanies();//RM0 - das0<BR>
+dasCustomerService.updateCustomers();//RM0 - das1<BR>
+----------------------------------------------------------------------------------------------------------------------------------------------<BR>
+<B>CASE2) also there can be - multiple RMs (multiple XAConnections for Tx support for atomic tx, if atomic is not needed can use java.sql.Connections)</B></P>
+
+<P>scaDomain1 = SCADomain.newInstance(&quot;company.composite&quot;);<BR>
+dasCompanyService = scaDomain.getService(CompanyService.class, &quot;CompanyComponent/CompanyServiceComponent&quot;);</P>
+
+<P>scaDomain2 = SCADomain.newInstance(&quot;customer.composite&quot;);<BR>
+dasCustomerService = scaDomain.getService(CustomerService.class, &quot;CustomerComponent/CustomerServiceComponent&quot;);</P>
+
+<P>dasCompanyService.updateCompanies(); //RM1 - das1<BR>
+dasCustomerService.updateCustomers(); //RM2 - das2<BR>
+----------------------------------------------------------------------------------------------------------------------------------------------<BR>
+<B>CASE3) case when at least one das (say das1) instance has a config with managedtx=true (i.e. das manages tx)</B><BR>
+In this case the configs and intents of all other das instances are immeterial, because to support managedtx=true (for das1), all others will need <BR>
+to follow the same mode.<BR>
+----------------------------------------------------------------------------------------------------------------------------------------------<BR>
+<B>CASE4) case when non-DBMS RMs are involved</B></P>
+
+<P>scaDomain1 = SCADomain.newInstance(&quot;company.composite&quot;);<BR>
+dasCompanyService = scaDomain.getService(CompanyService.class, &quot;CompanyComponent/CompanyServiceComponent&quot;);</P>
+
+<P>scaDomain2 = SCADomain.newInstance(&quot;jmscustomer.composite&quot;);<BR>
+jmsCustomerService = scaDomain.getService(jmsCustomerService.class, &quot;jmsCustomerComponent/jmsCustomerServiceComponent&quot;);</P>
+
+<P>dasCompanyService.updateCompanies(); //RM1 DBMS<BR>
+jmsCustomerService.updateCustomers(); //RM2 JMS<BR>
+--------------------------------------------------------------------------------------------------------------------------------------------------<BR>
+The Table2 from Tx Policy Draft needs to be considered.</P>
+
+<P>As the knowledge about das.implemnetation intent is at the construction of DASImplementationProvider(), but the knowledge of service level intent<BR>
+is at DASImplementationProvider.createInvoke() level, createInvoker() is the place which can take decision about tx control.</P>
+
+<P>The ConnectionInfo - finally present inside das (may it be from config.xml or .composite) should be in accordance with what is expected in the <BR>
+effective intents.</P>
+
+<P>DataAccessImplementationProvider.createInvoker() when calls getDAS() should pass as IN params the effective intents.</P>
+
+<P>When caller wants to pass xads (in case of global tx)/connection (in case of local tx), it needs a way to inject it (i.e. inject tx context) in <BR>
+the service. Some possible ways -<BR>
+**All DAS based services - can say mandatorily have a method setTransactionContext(Object ctx) (ctx can be Connection/XADS based on local<BR>
+or global). This should be invoked by the caller before calling any business method for the service. <BR>
+**Another way, from JIRA-1816 work - say the caller does<BR>
+GlobalTransactionContext.setContext(XADS) OR LocalTransactionContext.setContext(Connection).<BR>
+with this the thread context will have info to be used inside SCA component/services.<BR>
+DataAccessImplementationProvider will do getContext() and if it is available (i.e. caller did setContext), will pass it to the getDAS(),<BR>
+so das instance will get Connection during construction. </P>
+
+
+<P>---------------------------------------------------------------------------------------------------------------------------------------------------<BR>
+<B>I] propagatesTransaction + managedTransaction.global</B></P>
+
+<P>MEANING: caller will ideally start tx and pass the tx context to sca runtime. the tx is distributed xa tx.</P>
+
+<P>FLOW: <BR>
+i) during DataAccessImplementationProvider.createInvoker() <DIV class="error"><SPAN class="error">Unknown macro: {das=getDAS()}</SPAN> </DIV>, inents will be passed in as well as necessary info from<BR>
+txn context will be passed in by DataAccessImplementationProvider.<BR>
+ii) das will get constructed with passing &quot;new&quot; connection to FACTORY.createDAS(). Also set managedtx=false to enalble non-das tx management.</P>
+
+<P>the caller will be responsible to handle the txn (i.e. managed shared global txn pattern)</P>
+
+<P><B>example</B></P>
+
+<P>XADS= GlobalTransactionManager.getXADataSource(pass in properties);<BR>
+GlobalTransactionContext.setContext(XADS tied to XID); //due to threadlocal, this context is referenceable by DataAccessImplementationProvider now.<BR>
+GlobalTransactionManager.begin(GlobalTransactionContext.getContext());</P>
+
+<P>scaDomain = SCADomain.newInstance(&quot;company.composite&quot;);<BR>
+dasCompanyService = scaDomain.getService(CompanyService.class, &quot;CompanyComponent/CompanyServiceComponent&quot;);//needs XADS1 tied with same XID</P>
+
+<P>dasCustomerService = scaDomain.getService(CustomerService.class, &quot;CompanyComponent/CustomerServiceComponent&quot;);//needs XADS2 tied with same XID</P>
+
+<P>dasCompanyService.updateCompanies();//RM0 - das0 <BR>
+dasCustomerService.updateCustomers();//RM0 - das1</P>
+
+<P>GlobalTransactionManager.commit(context);//see that XID has 2 XADS tied to it and does necessaty actions for 2PC<BR>
+--------------------------------------------------------------------------------------------------------------------------------------------------<BR>
+Now for the case that, the caller is not having a ongoing tx and so does not inject tx context in sca runtime.</P>
+
+<P>When DASImplementationProvider detects there is no tx context set , inside createInvoker(), it can first instantiate das without a connection<BR>
+(some changes needed in tuscany-das-rdb for this), and then use das.getConfig() to get necessary config props and construct a tx context <BR>
+to be used by the current DASInvoker. Say we create a new DASTransactionCoordinator() for this work.</P>
+
+<P>DASTransactionCoordinator {</P>
+
+<P> GlobalTransactionContext setTxContext(dasConfig)<DIV class="error"><SPAN class="error">Unknown macro: {
+ XADS= GlobalTransactionManager.getXADataSource(pass in properties);
+ GlobalTransactionContext.setContext(XADS); //due to threadlocal, this context is referenceable by DataAccessImplementationProvider now.
+ GlobalTransactionManager.begin(GlobalTransactionContext.getContext());//starts tx, this tx will be shared by all invokers.
+ }</SPAN> </DIV></P>
+
+<P> //multiple XADS will need to be tied to single xid to make them part of 1 xa tx.<BR>
+ //more methods here for getContext, enqueXAResourceInXID, dqueue XAResource from XID, XID based 2PhaseCommit... <BR>
+}</P>
+
+<P>and will also pass &quot;new&quot; conection from the tx context to each new das instance.</P>
+
+<P>Also DASImplementationProvider() in this case will need to terminate tx. This can be done in stop() of DASImplementationProvider();<BR>
+start() can not be used to start a tx as at that time, there is no existing tx context.</P>
+
+<P>Questions:<BR>
+Now are my confusions. In DASImplementationProvider.stop() what is the way to know whether to commit/rollback? i.e. how stop() method will know about the invoke() having exceptions? Or otherwise each DASinvoker will need access to xid which is shared by all XAResources in the global tx<BR>
+and the DASInvoker is supposed to call DASTransactionCoordinator.rollback() for case of exception?</P>
+
+<P>Also, this whole story relates to only one RuntimeComponent (i.e. multiple services and multiple operations in each services but all in same <BR>
+component. Thus the tx can be encompassed by DASImplementationProvider.) What to do for the case when the global tx needs to span multiple <BR>
+components?<BR>
+------------------------------------------------------------------------------------------------------------------------------------------------<BR>
+<B>II] suspendsTransaction + managedTransaction.global</B><BR>
+Here even if caller has a tx, it will be ignored and DASImplementationProvider+DASTransactionCoordinator will create a new Tx context and <BR>
+will manage tx. Same questions as I]<BR>
+-------------------------------------------------------------------------------------------------------------------------------------------------<BR>
+<B>III] suspendsTransaction + managedTransaction.local</B></P>
+
+<P>DASImplementationProvider() will pass DASConfig.connectionInfo() to LocalTransactionManager.getDataSource() and setContext() to get <BR>
+java.sql.Connection (can be DriverManager or DataSource - in case of DataSource, the external env. is responsible for the JNDI initialization.)<BR>
+(As local tx, no question of XADS). Same question - how to communicate exception occuring in DASInvoker.invoke() to stop()?<BR>
+to decide whether to commit/rollback? Also as these are mere Connections and not XID/XADS etc. is it better for the DASInvoker() to control<BR>
+the commit/rollback of tx? i.e. each DASInvoker() thread will be a Local Tx.<BR>
+--------------------------------------------------------------------------------------------------------------------------------------------------<BR>
+<B>IV] suspendsTransaction + noManagedTransaction</B><BR>
+this is equivalent to a das config with managedtx=true.</P>
+
+<P>Now say in case, there are das1 and das2 involved from 2 different .composites in a caller's business method<BR>
+and das1 has IV] / managedtx=true and das2 has I], how will we be able to dectate that , because das1 is das managed tx, das2 should behave in <BR>
+same way?<BR>
+-------------------------------------------------------------------------------------------------------------------------------------------------<BR>
+Also, need to specify behavior for cases when only impl intent is present or only interaction intent is present.</P>
+
+<P>CASE2) and CASE4) in case of I] need the caller to manage tx. If this is not happening, how implementation.das will be able to manage tx <BR>
+(if there are multiple components involved)</P>
+ </DIV>
+ </DIV>
+ </DIV>
+ </TD>
+ </TR>
+ </TABLE>
+
+ <SCRIPT src="http://www.google-analytics.com/urchin.js" type="text/javascript">
+ </SCRIPT>
+ <SCRIPT type="text/javascript">
+ _uacct = "UA-1174707-5";
+ urchinTracker();
+ </SCRIPT>
+
+ <A href="http://www.statcounter.com/" target="_blank"><IMG src="http://c26.statcounter.com/counter.php?sc_project=2619156&java=0&security=94bd7e7d&invisible=0" alt="website stats" border="0"></A>
+
+ <DIV class="footer">
+ Copyright &copy; 2003-2007, The Apache Software Foundation&nbsp;&nbsp;
+ </DIV>
+
+ </BODY>
+</HTML> \ No newline at end of file