
git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@1640879 13f79535-47bb-0310-9956-ffa450edef68
264 lines
No EOL
18 KiB
HTML
264 lines
No EOL
18 KiB
HTML
|
|
<!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> |