Friday, June 20, 2014

ADF BC Reserved Mode for DB Connection Critical Applications

With this post I would like to explain how you can control ADF BC mode and switch from default managed to reserved mode and back. With default managed mode, there is no guarantee in ADF BC for DB connection to stay assigned for the user session. Why it is highly recommended to design your ADF application in such way to be compatible with default managed mode, there are exceptional scenarios when we want to guarantee DB connection to stay the same between requests. Reserved mode allows to guarantee DB connection and there is a way to switch between modes on runtime. You can read more in ADF developer guide - 40.4 Setting the Application Module Release Level at Runtime.

Sample application - ReservedModeADFApp.zip, is developed to demonstrate how you can switch between managed and reserved modes. You can change any field and click Prepare Data, this will post it to DB. By default, data will be lost during the next request. However, if you click Enable Reserved Mode - ADF BC will switch to reserved mode and DB connection will stay assigned, until you will switch back to managed mode again:


Prepare Data button calls ADF BC post operation, to post data to DB. There are two key methods here - enableReservedMode and disableReservedMode. As you can see, it is pretty straightforward to switch between modes, you only need to call setReleaseLevel method available as part of ADF BC API:


Application Module configuration is set with all default settings, also DB pooling is enabled:


We should test how it works to switch between two different modes - managed and reserved. Let's change data in any field, for example Hire Date:


Click Prepare Data button to post changes for Hire Date to DB:


Click Save button to commit transaction:


At last, click Cancel button to check if previously posted changes were committed to DB:


You can see - changes in Hire Date are reverted back, as change was not saved after it was posted. Application Module is set with DB pooling, means during each request it will return DB connection back to the pool and get another one on the next request. This would mean all changes posted to DB are lost:


This is correct behaviour. But in some exception cases, we would like to keep DB connection between requests. We could force this by switching Application Module into reserved mode. By default, when DB pooling is enabled, you can see there are zero DB connections used (connections are returned quickly to the pool after request completion):


We should repeat our test, but little different now. Before posting changes to DB, click Enable Reserved Mode button - this will switch Application Module to reserved mode and guarantee DB connection across requests:


You can see from the DB connection monitoring, one connection gets reserved now and stays assigned:


Click button Prepare Data now, to post changes to DB when reserved mode is on:


Click Save button to commit transaction:


Click Cancel button to see if recent changes will be reverted:


Changes are not lost this time, means posted data was successfully committed in the next request, when Save button was pressed:


Changes were posted and committed to DB, we can switch back to default managed mode. Click Disable Reserved Mode button:


You should see from DB connection monitoring graph, previously reserved DB connection should be returned back to the pool:

14 comments:

Unknown said...

Thank you for this post. Can you please share your vision how to deal with hanged AM instances released in reserved mode, for example, when user closes a browser?
I know thre's some request from browser in ADF 12c when user closes browser tab. Can we intercept this request and release AM? Can we override AM instance lifecycle timeouts when we set up reserverd mode?
Thank you.

Andrej Baranovskij said...

Hi Fedir,

You could adjust AM timeout to be shorter, when AM is switched to reserved mode, this means AM will be closed faster, when no activity.

Obviously with reserved mode, you should plan number of DB connections and number of AM instances more carefully. Typically, reserved mode is not suitable for Web apps (when number of concurrent users is not known in advance). But, if you have enterprise internal app with max 100 users (for example), you could estimate number of DB connections needed quite accurate.

I was planning similar topic for the one of next blog posts, to research how to deal with browser closing. Stay tuned.

Thanks,
Andrejus

Unknown said...

Thanks for reply, Andrejus.
I have a special interest in it as I often asked about possibility to migrate 2-layer applications to ADF, and there are some cases when there is a need to hold a database session for some time. Minimum is to execute an operation, then to see some result output and then to confirm/cancel an operation.

I tried to play with timeouts in your example app, and i saw that connections are held for hours after browser tab close. It didn't helped. Bad thing in this case is that when you open a DB transaction you get DB objects locked. And if user re-logins he cannot continue his work because of it.

Andrej Baranovskij said...

Timeouts must be correctly set - then it works fine. More details in the one of the next blog posts. Stay tuned.

Andrejus

MA said...

Thanks Andrejus for the post
When I disables application moudle pooling and disabled reserved mode the data didn't lost and worked with no problem although pooling is disabled and reserved mode also disabled.
I need an explanation for this.

Andrej Baranovskij said...

Yes, of course - when DB pooling is off (default), AM keeps DB connection. But there is no guarantee for how long it will keep it, this is the main difference with reserved mode. Passivation/Activation could happen between two requests on higher load and then your data will be lost. Reserved mode guarantees DB connection to be assigned for AM, not matter what load is on the system. I hope is more clear now.

Regards,
Andrejus

MA said...

Thanks Andrejus for clarification i thought that when Application Module pooling is disabled, data is passivated and DB connection is released after each request, but you clarified that this happen only on higher load only.
Thanks

Andrej Baranovskij said...

I was talking about DB pooling, it is disabled by default and connection stays assigned, until higher load. If you disable AM pooling (different thing), then connection will be released after each request and data will be lost.

Anyway, I plan to post several additional posts on this topic, to clarify it in more detail.

Regards,
Andrejus

Krishna said...

Hi Andrejus
I am wondering how application would behave in case of fail-over/high availability?

Thanks
Krishna

Andrej Baranovskij said...

Hi,

I would doubt using failover anyway, it makes sense just to start new Web browser session, if current session fails.

There are too many performance side effects of enabling high availability.

Regards,
Andrejus

Andrej Baranovskij said...

Hi Fedir,

You can handle browser tab close with WebSocket in ADF 12c. Based on event received by WebSocket, we can logout session programmatically.

Regards,
Andrejus

rvd said...

Hi Andrejus,

We have a similar situation where we are dependent on DB Sessions for our critical application. we are using 11.1.2.4. We are thinking to use this approach to solve our issue. We saw your reply in one of the comments above for "how to deal with hanged AM instances released in reserved mode, for example, when user closes a browser".
For this you have replied like you are preparing for another post to handle this in web application. can you please suggest on this?
Say like we have 100 users, what is the maximum timeout we can give to handle hanged AMs?

Andrej Baranovskij said...

You can use reserved mode and handle logout through WebSocket, on browser close - https://andrejusb.blogspot.lt/2016/01/automatic-adf-logout-on-browser-close.html

Regards,
Andrejus

Unknown said...

Hi Andrejus,

We have similar scenario like rvd mentioned. We are also using 11.1.2.4. We cannot move to 12c as of now. And one more complexity is that, we are rendering our application through iframe due to some architechtural reasons. (Soon we will change the way it renders as normal application in the next release). But as of now we don't know how to handle it.(If we follow the above approach we will be having lots of hanging AMs due to rendering the application as iframe). Please give us your valuable inputs

Regards,
Mathiarul.