Tuesday, August 16, 2011

Rollback is executed when a region is refreshed

We are using Task flows as regions in jdeveloper in the latest project.
I have just noticed that when a region refreshes then a data control transaction rollback is executed transparently.
This does not happen the first time the region is displayed but every time it is refreshed after that.
This cause unexpected behavior of loosing data and the current rows of any other shared transaction task flow.

Could this be an expected (designed) functionality? Why?

As a test case I have 2 application modules (DepartmentsModule and Employees module) and a page that has departments and a region that has Employees with ‘share transaction if possible’ in the EmployeesTaskFlow.
Also the EmployeesTaskFlow get as parameter the current DepartmentId and has Refresh condition ifNeeded so that it refresh every time I navigate into departments.

Yet when I press next button I loose any change made on current department and I stay in the same row.
What I see in log is that Rollback is executed as a consequence of region Refresh and releaseViewPort.

Is this expected behavior or a bug?

I will check also what happens in 11.1.2 that it seems the nesting implementation have changed:

It reproduce also in 11.1.2

Test Case

A Perfect explanation and solution is given by Oracle Support. I will put it as is here:
@ At the point when the customer decided the region should share the
@ transaction with its parent, he also made the region a potential actor on the
@ parent transaction. Since the transaction mode on the region is not 'Always
@ Use Existing Transaction', the region transaction is not necessarily created
@ by the parent (and I will come back to that later), the behavior of the
@ region becomes the behavior of the parent even if they don't share the same
@ datacontrol. That is because both datacontrol are in one transaction since
@ the transaction is shared. When the region refresh, it rollback the
@ transaction which rollback both datacontrol.
@ .
@ To make the share mode work, the main point the customer should pay attention
@ to is that the transaction should be created by the parent, not by the
@ region. If it is created by the region, then the region become the owner of
@ the transaction and will rollback when the region is refreshed. If the
@ transaction was created by the parent it will work as expected.
@ .
@ What you need to do is ensure that the transaction is owned by the parent.
@ You need to have it created before the region. They are several ways to do
@ that:
@ 1) Have the parent page in a bounded taskflow with 'Always Begin New
@ Transaction' mode on.
@ 2) Call beginTransaction() on the DataControlFrame in an action that
@ navigates to the parent page with the region.
@ 3) Have a method activity that executes beginTransaction() on a request bean
@ before navigating to the parent page with the region.
@ The code to do begin the transaction is:
@ .
@ public void beginTransaction()
@ {
@ BindingContext context = BindingContext.getCurrent();
@ .
@ String dcFrameName = context.getCurrentDataControlFrame();
@ DataControlFrame dcFrame = context.findDataControlFrame(dcFrameName);
@ dcFrame.beginTransaction(new TransactionProperties());
@ }
@ .
@ To prevent the region from owning the transaction and run into these types of
@ issue for share mode, you can set the transaction mode on the taskflow to:
@ or 'Always Use Existing Transaction' in the
@ property inspector. If the transaction does not exist, an exception is
@ thrown.
@ .
@ I modified the original test case to illustrate the different options. Open
@ the workspace and look at adfc-config.xml. Run the Start page, withoutTrans
@ is the original test case, withTrans and beginTrans are 2 options that work.
@ .

Resolution Test Case

Unfortunately it seems that the issue is not fully resolved.
This works until a Data control frame commit or Rollback is executed.
Then it seems that the parrent looses control again of the transaction and regions rollback again on every refresh...
In the test case i added 2 buttons that do :

DataControlFrame dcFrame = context.findDataControlFrame(dcFrameName);
DataControlFrame dcFrame = context.findDataControlFrame(dcFrameName);

The test case work fine until any of the commit or rollback transaction is pressed
Then Next button still causes rollback to be executed.

This means that still i cannot control the full data control frame transaction when i have regions with parameters.

New test case

No comments:

Post a Comment