summaryrefslogtreecommitdiffstats
path: root/site/trunk/site-publish/transaction-intents-and-transaction-manager-support.html
blob: 36ffddcc69936dd8cfd86e3112d709937931c349 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
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>