diff options
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.html | 264 |
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%"> + + </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%"> + <A href="home.html" title="Apache Tuscany">Apache Tuscany</A> > <A href="home.html" title="Home">Home</A> > <A href="menus.html" title="Menus">Menus</A> > <A href="subproject-menus.html" title="Subproject Menus">Subproject Menus</A> > <A href="das-java-subproject-menu.html" title="DAS Java Subproject Menu">DAS Java Subproject Menu</A> > <A href="design-discussions.html" title="Design Discussions">Design Discussions</A> > <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> + </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> 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> At das.implementation level intents can be - managedTransaction.global, managedTransaction.local, noManagedTransaction, (still not clear why to support unqualified managedTransaction)<BR> +c> At present, implementation.das does not support oneWayInvocation - so need not consider transactedOneWay and immediateOneWay - is this right assumption?<BR> +d> 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("company.composite");<BR> +dasCompanyService = scaDomain.getService(CompanyService.class, "CompanyComponent/CompanyServiceComponent");</P> + +<P>dasCustomerService = scaDomain.getService(CustomerService.class, "CompanyComponent/CustomerServiceComponent");</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("company.composite");<BR> +dasCompanyService = scaDomain.getService(CompanyService.class, "CompanyComponent/CompanyServiceComponent");</P> + +<P>scaDomain2 = SCADomain.newInstance("customer.composite");<BR> +dasCustomerService = scaDomain.getService(CustomerService.class, "CustomerComponent/CustomerServiceComponent");</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("company.composite");<BR> +dasCompanyService = scaDomain.getService(CompanyService.class, "CompanyComponent/CompanyServiceComponent");</P> + +<P>scaDomain2 = SCADomain.newInstance("jmscustomer.composite");<BR> +jmsCustomerService = scaDomain.getService(jmsCustomerService.class, "jmsCustomerComponent/jmsCustomerServiceComponent");</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 "new" 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("company.composite");<BR> +dasCompanyService = scaDomain.getService(CompanyService.class, "CompanyComponent/CompanyServiceComponent");//needs XADS1 tied with same XID</P> + +<P>dasCustomerService = scaDomain.getService(CustomerService.class, "CompanyComponent/CustomerServiceComponent");//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 "new" 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 © 2003-2007, The Apache Software Foundation + </DIV> + + </BODY> +</HTML>
\ No newline at end of file |