Multiple root Application Modules sharing the same transaction context !

I'm not sure how many of you noticed the following section in Fusion Developers Guide - 10.2.6 What You May Need to Know About Shared Application Modules and Connection Pooling. This part talks about an AM configuration parameter 'jbo.shared.txn' which can be used for sharing entity cache and DB connection across multiple root application modules. You just need to key in same string value for 'jbo.shared.txn' using the properties page of the editor for the bc4j.xcfg file of the root application modules.

Please note that this property is applicable for shared as well as non shared Application Modules(though originally designed for non-shared AM). Interestingly, this is used internally by the declarative taskflow transaction to allow the ADF BC Data Controls to share a DBTransaction. I'm copying the relevant content from developers guide below for a quick reference...

When your application defines more than one shared application module, you can change the default to optimize database connection usage by defining a named transaction for each root application module to use. The transaction name is an arbitrary string that you set on the jbo.shared.txn property in the Properties page of the editor for the bc4j.xcfg file of the root application module. At runtime, the root application modules with the same jbo.shared.txn property setting (identified by the string you supply) will share the same database connection and etity cache

Note: Please note that in the above case the transaction would be shared (across user sessions) between all Application Modules having the same 'jbo.shared.txn' value. In case of task flow, the data binding layer supplies the jbo.shared.txn value derived from user session to ensure unique value for each user session(transaction context). And this is of course driven by the transaction attribute you set for task flow at design time.


Learn More ...

There are a lot more points like this. If  you are curious to learn the internals of the ADF Business Components and ADF Binding Layer,  the following book is for you - Oracle ADF Real World Developer’s Guide.
More details about this book can be found in this post- http://jobinesh.blogspot.in/2012/07/pre-order-your-copy-of-oracle-adf-real.html

Comments

Carlos Miranda said…
im trying to set the property but im not doing it well.
could you post bc4j.xcfg sample?
Jobinesh said…
Carlos,
Its very starlight forward.You can try building one.
1. Pick up 2 ApplicationModule having some common EO
2. Key in the same value for 'jbo.shared.txn' on both AM config using configuration window
3. Build two pages, each using different AM. Then you can observe the transaction sharing behavior. If you modify something on page1, same changes appears on page 2 as well, even if they are using 2 AMs
Mukul said…
Hi Jobinesh,
First of all ,...your blog is a wonderful effort for ADF dev community.
Now a small question, I have written a custom EnvInfoProvider which implements oracle.jbo.common.ampool.EnvInfoProvider interface to set dynamic properties for all AMs in my project programatically .
Now going by this article if I set to 'jbo.shared.txn' dynamically to a unique sequence for each user HTTP session for all root AMs in the project, that means for that session , all root AMs in the project will share the same database connection?
If yes, this concept is big plus on performance side as one user session will always use one jdbc connection which otherwise is dependent on number of root application modules.Let me know your thoughts on this.

Also , i have added you on gtalk, if you don't mind would you like to share ur gtalk id or mobile, i won't bother u much :)!

Regards,
Mukul Gupta(gupta.mukul@gmail.com)
Solution Architect
Fujitsu
Mukul said…
Hi Jobinesh,
First of all thanks for the wonderful blog on ADF.

A quick question with respect of existing article. A negative point on the ADF side is that each root application module acquires its own jdbc connection, which gradually results out in large number of innactive jdbc connections if you are building on a large project in distributed teams, so, gradually requires tuning.
Now using the present article idea if 'jbo.shared.txn' is same for different root application modules, they will share same jdbc connection across HTTP user sessions.
Now to make AM jdbc connection unique based on a particular HTTP session for all root AMs, we can write a custom EnvInfoProvider class where we can set 'jbo.shared.txn' unique in a particular user http session, so that all AMs in one HTTP user session share same jdbc connection in all root modules?

Is this correct or not? Also, I wanted to include you on gtalk , my id is gupta.mukul@gmail.com , if possible please include me... won't bother you much :) ! Or else you can share your contact number.

--Mukul
Solution Architect
Fujitsu
Aravindan said…
Nice article. I have a scenario where a custom method in the app module needs to participate in the XA transaction. For e.g. this custom method would be exposed through AM service interface. This method would be performing some db activities. Now assume that a SOA service is making 3-4 sequence of calls to some other external systems. In between it is calling our custom method as well. Like
1) call to extenal system 1
2) call to external system 2
3) call to AM's method through service interface.
4) call to extenal system 3.

In the above scenario, if any one of the call fails, SOA service has to rollback all the steps. Can the AM's custom method (3rd step) participate in such transation and rolled back after 4 th step fails?
Jobinesh said…
Well, you may need to ty calling ApplicationModule::postChanges() instead of commit(). That should be enough to handle DB level 2 phase commit. Challenge may be sending notification to AM during roll back from third party service...Pleas e give a try and let me know if you face any issues during rollback
Aravindan said…
Thanks Jobinesh. Before i try this, i have a question. Since i'm service enabling my app module, how can i make it participate in the transaction. Isn't the SOA service call to BC service interface stateless? For e.g. if i do postChange() in the first attempt of SOA call, then when SOA has to rollback or commit how will I get the same app module instance?
Thanks for the experiment. It was very informative and useful. I keep in mind. Thanks a lot for sharing such a awe-some information.
sunny said…
I have a scenario ,lets say i got Dep table from one AM and Emp table from Second AM.
And i got to insert a new Dept and Emp under this Dept.
Can i do that and if so how?
Vikas Modhale said…
Hi Jobinesh,

I did same config








But some where something is going wrong and I am getting error after UI is ideal for some time.

Is it happening because of AM-Pooling config I did?

java.lang.NullPointerException
at oracle.jbo.server.DBTransactionImpl.processPendingEvents(DBTransactionImpl.java:5776)
at oracle.jbo.server.ApplicationModuleImpl.getSyncLock(ApplicationModuleImpl.java:388)
at oracle.jbo.server.ApplicationModuleImpl.doPoolMessage(ApplicationModuleImpl.java:9072)
at oracle.jbo.common.ampool.ApplicationPoolImpl.sendPoolMessage(ApplicationPoolImpl.java:4607)
at oracle.jbo.common.ampool.ApplicationPoolImpl.manageReferencingState(ApplicationPoolImpl.java:1493)
at oracle.jbo.common.ampool.ApplicationPoolImpl.finalizeResource(ApplicationPoolImpl.java:1393)
at oracle.jbo.pool.ResourcePool.removeResourceInternal(ResourcePool.java:848)
at oracle.jbo.pool.ResourcePool.setState(ResourcePool.java:1103)
at oracle.jbo.pool.ResourcePool.gc(ResourcePool.java:1560)
at oracle.jbo.pool.ResourcePool.wakeup(ResourcePool.java:873)
at oracle.jbo.pool.ResourcePool.wakeup(ResourcePool.java:878)
at oracle.jbo.pool.ResourcePoolMonitor.run(ResourcePoolMonitor.java:121)
at java.util.TimerThread.mainLoop(Timer.java:512)
at java.util.TimerThread.run(Timer.java:462)
Vikas Modhale said…
Hi Jobinesh,

I did same config
AppModuleConfig DeployPlatform="LOCAL" jbo.shared.txn="TEST" jbo.project="xyz.model.Model" name="TransactionAppModuleLocal" ApplicationName="xyz.TransactionAppModule">
AM-Pooling jbo.ampool.timetolive="600000" jbo.ampool.maxinactiveage="300000" jbo.ampool.monitorsleepinterval="300000"
Database jbo.locking.mode="optimistic"
Security AppModuleJndiName="xyz.TransactionAppModule"
Custom JDBCDataSource="jdbc/TESTDataSource"
/AppModuleConfig>

But some where something is going wrong and I am getting error after UI is ideal for some time.

Is it happening because of AM-Pooling config I did?

java.lang.NullPointerException
at oracle.jbo.server.DBTransactionImpl.processPendingEvents(DBTransactionImpl.java:5776)
at oracle.jbo.server.ApplicationModuleImpl.getSyncLock(ApplicationModuleImpl.java:388)
at oracle.jbo.server.ApplicationModuleImpl.doPoolMessage(ApplicationModuleImpl.java:9072)
at oracle.jbo.common.ampool.ApplicationPoolImpl.sendPoolMessage(ApplicationPoolImpl.java:4607)
at oracle.jbo.common.ampool.ApplicationPoolImpl.manageReferencingState(ApplicationPoolImpl.java:1493)
at oracle.jbo.common.ampool.ApplicationPoolImpl.finalizeResource(ApplicationPoolImpl.java:1393)
at oracle.jbo.pool.ResourcePool.removeResourceInternal(ResourcePool.java:848)
at oracle.jbo.pool.ResourcePool.setState(ResourcePool.java:1103)
at oracle.jbo.pool.ResourcePool.gc(ResourcePool.java:1560)
at oracle.jbo.pool.ResourcePool.wakeup(ResourcePool.java:873)
at oracle.jbo.pool.ResourcePool.wakeup(ResourcePool.java:878)
at oracle.jbo.pool.ResourcePoolMonitor.run(ResourcePoolMonitor.java:121)
at java.util.TimerThread.mainLoop(Timer.java:512)
at java.util.TimerThread.run(Timer.java:462)
Jobinesh said…
Vikas
Before answering your questions, May I know your use case. Note that this property is primarily designed for using in shared AM so that all instances of shred AM use DB connection + Txn. If you use it for root AM all isntances of this root AM will share same Txn across all user sessions (at App level). Is that you are looking for?
Vikas Modhale said…
Hi Jobinesh

In my use-case I am using all root application module and all application modules have only read only view objects (NO entity's Objects / no commits on AM) and web service calls,

so I want to open only one database connection across all application module for one user session , so that's why I am sharing txn .

can you pleas advise me what should I config in application module.

Thanks

Vikas
Jobinesh said…
I don't recommend it for root AMs if there are many concurrent requests accessing it. This is because there is great chance for multiple threads to wait on same DB connection which may eventually affect your systems performance. configuration wise whatever mentioned in the blog is enough
Unknown said…
Dear Jobinesh,

Thanks for your helpful information.
In my previous projects I had one Root Application Module for all use cases to serve all user requests. So, I had only one DB Connection and Transaction per user. But my Root Application Module includes all the View Objects and Application Modules in the system and this makes it a huge object.
I was going to use BC4JDataControl.TransactionName in Databindings.cpx. After reading your bolog, I realized that after setting TransactionName, DataControlFactory sets jbo.shared.txn behind the scene. To use this facility to achieve the goal (One DB Connection and Transaction per user session), I have to set TransactionName based on something like SessionID. I haven't found any documention about BC4JDataControl.TransactionName to find the side effects. I was wondering if I could have your opinion about this idea. I think concurrent requests of same user won't be the problem, because even without using jbo.shared.txn all requests in one http session are served by the same Application Module and DBTransaction.

Best Regards,
Mehdi

Disclaimer

The views expressed on this blog are my own and do not necessarily reflect the views of my employer.