Transaction Intents and Transaction Manager support (TUSCANY) created by Amita 
Vadhavkar
   
http://cwiki.apache.org/confluence/display/TUSCANY/Transaction+Intents+and+Transaction+Manager+support

Content:
---------------------------------------------------------------------

As this topic involves a lot of discussion thought the better place will be 
wiki.

I was just thinking randomly to see how to integrate the work in JIRA-1816 with 
the work
in JIRA-1700(implementation.das support for tx inents/policies). Below are some 
suggestions I could gather,
but need lot of feedback and ideas.

h3. TransactionManager support in  SCA (JIRA-1816)
---------------------------------------------------------------------------------------------------------------------------------
TransactionInfo - can have 2 subclasses - GlobalTransactionInfo 
(XADataSource...), LocalTransactionInfo (Connection...)
we can rename TransactionInfo to TransactionContext if it suits.

TransactionManager - also can have 2 similar flavours - LocalTransactionManager 
(what is there in the transaction.zip today)
and GlobalTransactionManager. GlobalTransactionManager can support say a class 
level annotation - @TransactionManagerFactory(Geronimo)
to have a way to inject an externally available TransactionManager like 
Geronimo, JOTM etc.
---------------------------------------------------------------------------------------------------------------------------------

h3. Tx Policy Support in implementation.das (JIRA-1700)

----------------------------------------------------------------------------------------------------------------------------------------------
I went through the Tx Policy Draft and trying to understand it in detail. Below 
trying to give examples of different scenarions
for implementation.das and attempting to analyze just some part from that. 
Getting lost in different places :). Need all possible comments.
I am just gathering all points below, with some discussions can prepare a 
design doc if that helps.

(RM=Resource Manager) (xads = XADataSource) 
(xares=XAResource)(conn=connection)(2PC - 2 Phase Commit)
----------------------------------------------------------------------------------------------------------------------------------------------
Note: 
a> It is possible that the caller (say junit test case) passes 
XADataSource(which has Connection and XAResource) OR same can be obtained from 
within SCA runtime.
b> At das.implementation level intents can be - managedTransaction.global, 
managedTransaction.local, noManagedTransaction, (still not clear why to support 
unqualified managedTransaction)
c> At present, implementation.das does not support oneWayInvocation - so need 
not consider transactedOneWay and immediateOneWay - is this right assumption?
d> At service level intents can be - propagatesTransaction, suspendsTransaction
----------------------------------------------------------------------------------------------------------------------------------------------
Scenarios:- 

*CASE1) 1 component - 1 impl - 1 connection info - multiple services - multiple 
operations/service*

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.
i.e. during DASImplementationProvider.createInvoker().

1 impl == 1 RM (multiple Connections/XAConnections). 
so multiple services in the same .composite will use the same RM

In DASImplementationProvider(component, impl) we have 
DASImplementationProvider.createInvoker(service, operation)
One DASImplementationProvider has 1 DataAccessEngineManager. Bue each 
createInvoker() has a new DASInvoker() with new das
and new DataAccessEngine. So each new invoker() will have a diff das instance.

*example*

scaDomain = SCADomain.newInstance("company.composite");
dasCompanyService = scaDomain.getService(CompanyService.class, 
"CompanyComponent/CompanyServiceComponent");

dasCustomerService = scaDomain.getService(CustomerService.class, 
"CompanyComponent/CustomerServiceComponent");

dasCompanyService.updateCompanies();//RM0 - das0
dasCustomerService.updateCustomers();//RM0 - das1
----------------------------------------------------------------------------------------------------------------------------------------------
*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)*

scaDomain1 = SCADomain.newInstance("company.composite");
dasCompanyService = scaDomain.getService(CompanyService.class, 
"CompanyComponent/CompanyServiceComponent");

scaDomain2 = SCADomain.newInstance("customer.composite");
dasCustomerService = scaDomain.getService(CustomerService.class, 
"CustomerComponent/CustomerServiceComponent");

dasCompanyService.updateCompanies(); //RM1 - das1
dasCustomerService.updateCustomers(); //RM2 - das2
----------------------------------------------------------------------------------------------------------------------------------------------
*CASE3) case when at least one das (say das1) instance has a config with 
managedtx=true (i.e. das manages tx)*
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 
to follow the same mode.
----------------------------------------------------------------------------------------------------------------------------------------------
*CASE4) case when non-DBMS RMs are involved*

scaDomain1 = SCADomain.newInstance("company.composite");
dasCompanyService = scaDomain.getService(CompanyService.class, 
"CompanyComponent/CompanyServiceComponent");

scaDomain2 = SCADomain.newInstance("jmscustomer.composite");
jmsCustomerService = scaDomain.getService(jmsCustomerService.class, 
"jmsCustomerComponent/jmsCustomerServiceComponent");

dasCompanyService.updateCompanies(); //RM1 DBMS
jmsCustomerService.updateCustomers(); //RM2 JMS
--------------------------------------------------------------------------------------------------------------------------------------------------
The Table2 from Tx Policy Draft needs to be considered.

As the knowledge about das.implemnetation intent is at the construction of 
DASImplementationProvider(), but the knowledge of service level intent
is at DASImplementationProvider.createInvoke() level, createInvoker() is the 
place which can take decision about tx control.

The ConnectionInfo - finally present inside das (may it be from config.xml or 
.composite) should be in accordance with what is expected in the 
effective intents.

DataAccessImplementationProvider.createInvoker() when calls getDAS() should 
pass as IN params the effective intents.

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 
the service. Some possible ways -
**All DAS based services - can say mandatorily have a method 
setTransactionContext(Object ctx) (ctx can be Connection/XADS based on local
or global). This should be invoked by the caller before calling any business 
method for the service.  
**Another way, from JIRA-1816 work - say the caller does
GlobalTransactionContext.setContext(XADS) OR 
LocalTransactionContext.setContext(Connection).
with this the thread context will have info to be used inside SCA 
component/services.
DataAccessImplementationProvider will do getContext() and if it is available 
(i.e. caller did setContext), will pass it to the getDAS(),
so das instance will get Connection during construction. 


---------------------------------------------------------------------------------------------------------------------------------------------------
*I] propagatesTransaction + managedTransaction.global*

MEANING: caller will ideally start tx and pass the tx context to sca runtime. 
the tx is distributed xa tx.

FLOW: 
i) during DataAccessImplementationProvider.createInvoker() {das=getDAS()}, 
inents will be passed in as well as necessary info from
txn context will be passed in by DataAccessImplementationProvider.
ii) das will get constructed with passing "new" connection to 
FACTORY.createDAS(). Also set managedtx=false to enalble non-das tx management.

the caller will be responsible to handle the txn (i.e. managed shared global 
txn pattern)

*example*

XADS= GlobalTransactionManager.getXADataSource(pass in properties);
GlobalTransactionContext.setContext(XADS tied to XID); //due to threadlocal, 
this context is referenceable by DataAccessImplementationProvider now.
GlobalTransactionManager.begin(GlobalTransactionContext.getContext());

scaDomain = SCADomain.newInstance("company.composite");
dasCompanyService = scaDomain.getService(CompanyService.class, 
"CompanyComponent/CompanyServiceComponent");//needs XADS1 tied with same XID

dasCustomerService = scaDomain.getService(CustomerService.class, 
"CompanyComponent/CustomerServiceComponent");//needs XADS2 tied with same XID

dasCompanyService.updateCompanies();//RM0 - das0 
dasCustomerService.updateCustomers();//RM0 - das1

GlobalTransactionManager.commit(context);//see that XID has 2 XADS tied to it 
and does necessaty actions for 2PC
--------------------------------------------------------------------------------------------------------------------------------------------------
Now for the case that, the caller is not having a ongoing tx and so does not 
inject tx context in sca runtime.

When DASImplementationProvider detects there is no tx context set , inside 
createInvoker(), it can first instantiate das without a connection
(some changes needed in tuscany-das-rdb for this), and then use das.getConfig() 
to get necessary config props and construct a tx context 
to be used by the current DASInvoker. Say we create a new 
DASTransactionCoordinator() for this work.

DASTransactionCoordinator {

  GlobalTransactionContext setTxContext(dasConfig){
    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.
  }
  
  //multiple XADS will need to be tied to single xid to make them part of 1 xa 
tx.
  //more methods here for getContext, enqueXAResourceInXID, dqueue XAResource 
from XID, XID based 2PhaseCommit...  
}

and will also pass "new" conection from the tx context to each new das instance.

Also DASImplementationProvider() in this case will need to terminate tx. This 
can be done in stop() of DASImplementationProvider();
start() can not be used to start a tx as at that time, there is no existing tx 
context.

Questions:
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
and the DASInvoker is supposed to call DASTransactionCoordinator.rollback() for 
case of exception?

Also, this whole story relates to only one RuntimeComponent (i.e. multiple 
services and multiple operations in each services but all in same 
component. Thus the tx can be encompassed by DASImplementationProvider.) What 
to do for the case when the global tx needs to span multiple 
components?
------------------------------------------------------------------------------------------------------------------------------------------------
*II] suspendsTransaction + managedTransaction.global*
Here even if caller has a tx, it will be ignored and 
DASImplementationProvider+DASTransactionCoordinator will create a new Tx 
context and 
will manage tx. Same questions as I]
-------------------------------------------------------------------------------------------------------------------------------------------------
*III] suspendsTransaction + managedTransaction.local*

DASImplementationProvider() will pass DASConfig.connectionInfo() to 
LocalTransactionManager.getDataSource() and setContext() to get 
java.sql.Connection (can be DriverManager or DataSource - in case of 
DataSource, the external env. is responsible for the JNDI initialization.)
(As local tx, no question of XADS). Same question - how to communicate 
exception occuring in DASInvoker.invoke() to stop()?
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
the commit/rollback of tx? i.e. each DASInvoker() thread will be a Local Tx.
--------------------------------------------------------------------------------------------------------------------------------------------------
*IV] suspendsTransaction + noManagedTransaction*
this is equivalent to a das config with managedtx=true.

Now say in case, there are das1 and das2 involved from 2 different .composites 
in a caller's business method
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 
same way?
-------------------------------------------------------------------------------------------------------------------------------------------------
Also, need to specify behavior for cases when only impl intent is present or 
only interaction intent is present.

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 
(if there are multiple components involved)

---------------------------------------------------------------------
CONFLUENCE INFORMATION
This message is automatically generated by Confluence

Unsubscribe or edit your notifications preferences
   http://cwiki.apache.org/confluence/users/viewnotifications.action

If you think it was sent incorrectly contact one of the administrators
   http://cwiki.apache.org/confluence/administrators.action

If you want more information on Confluence, or have a bug to report see
   http://www.atlassian.com/software/confluence



---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to