We have a problem we hope you can help solve, using JDeveloper 10.1.2.3.0 with JHeadStart 10.1.3.3.87 and its easy to reporduce and its a bad one.
Create a simple web project > Create Entity/VO for one table > Enable JHeadStart >
Use JHS to create Master Detail drill down single record
Run app > Open Browser to the Master list > press button Create X to bring up a new row NOW open another browser TAB and do the same so we have 2 forms open in INSERT mode.
Press Save on 1st tab to trigger the Insert - fine it reloads the form after commit and row is in the DB THEN switch to the other tab and submit that one > this one will overwire the record you entered 1st.
This is bad and its happening often when we load the system with many users event without multiple (multiple tabs makes it easy to test) - trapping the doDML we expect the 2nd insert request to be DML_INSERT but we get DML_UPDATE. Depending on refresh setting on some attributes we will get error back JBO-25014 but if no refresh on insert update you still get the same issue only one row in db and 1st row gets over written.
If you have any ideas what is going on and how to solve this ASAP that would be great.
This effect also does not occur:
- running two Model (app module) testers siimultaneously.
- without JHeadstart (ADF versions 10.1.3.2, 10.1.3.4, 184.108.40.206)
- with or without JHeadstart 220.127.116.11.33 (ADF 18.104.22.168)
Well, the two browser tabs share the same session, so that might explain it.
Are you saying you can even reproduce this wilt multiple users, using separate browser instances?
That would surpirse me.
One reason you get this behavior is that ADF 10.1.3 had a buggy "browser back" button protection that we disable with JHeadstart.
Maybe it is related to that. You can try swithcing it on again by manually setting the page definition property "EnableTokenValidation" to "true" in all your page defs and see whether that fixes this specific issue.
Thanks for the entry. Yes, we realized that the two-tab browser scenario was the same session. The thing that baffled us was why our test without JHS allowed two inserts in a two-tab, same session situation whereas with JHS, the second insert did an update on the first record committed. We suspected it had something to do with how the current row pointer in the view cache/entity cache was being handled.
The main symptom we started with was that users in separate sessions in production are overwriting each other's records; and we agree with you, it is surprising but we can reproduce it when traffic is "heavy" (more than four users usually) or the operations are rapid fire -- less than a minute between User 1 inserting a record and User 2 inserting a record. The second user insert operation acutally updates user 1's record even though the data for both inserts is different.
We switched EnableTokenValidation to "true" and this "fixes" the two-tab, single session situation -- the second insert presents a row currency JBO error (much better than overwriting the first record). In a two-user session scenario, the effect is worse with this setting: the second user trying to insert actually updates a different record from the record the first user just inserted.
This seems to point to users sharing a view/entity cache and it seems like that might be an ADF or maybe an OC4J bug -- we are using datasources on OAS and an HTTPS protocol for this app.
So next we are going to try using a database procedure that overrides the Save operation on new (and updated) records. If the database procedure sees a negative ID (from DBSequence) it will insert regardless of the current record pointer. If the database procedure sees a positive ID, it will update that record. I think we'll also need to roll back the CreateInsert that got us to the new record screen, too. Messy, yes, but if this effect is due to an ADF 10.1.3 bug, rewriting the app in 11g would take much longer.
Our other ADF JHS 10.1.3 apps do not have this problem as far as we know, but they do not use datasources or HTTPS.
It is also worth testing your application with app module pooling switched off if you haven't done so yet.
The fact that the problem starts with multiple concurrent users, might indicate it is related to AM pooling and might be caused by coding errors in ADF BC that only occur under heavy load, for example using member variables that keep the same value when an instance is recycled for another user.
We had not tried disabling AM pooling but after doing that today we found that a save reported success on the page but nothing was actually saved to the database. Turning AM pooling back on allowed the save to work again but we still have the overlapping session effect. The following seems to confirm that AM pooling is a good thing: AM Pool disabled & Pessimistic locking mode
The next test will be deploying on HTTP instead of HTTPS.
After that, we will try substituting the procedure to update or insert instead of the framework save -- then we will throw away the view cache new record with a rollback. The insert procedure seems to work with the two-tabs-in-one-session scenario, at least (although that is not a true reflection of the production situation).
Since this seems to be a bad ADF BC bug with this version, any other ideas we could try -- even if they seem like long shots -- would be appreciated. Upgrading to a new version of ADF is a last resort, unfortunately.
With switching off AM pooling you simulate heavy load of your system, see http://docs.oracle.com/cd/E16162_01/web.1112/e16182/bcstatemgmt.htm#CHDGAIFA
The fact that changes are not saved when tuning off AM pooling indicates that the problem might be in your own ADF BC code that is not actication/passivation safe.
If you think it is a bug in ADF BC I suggest you raise this with Oracle Support to get confirmation.
Thanks for pointing to that doc and the activation-safety issue.
Our procedure workaround seems to hold for the problem screen, but now we're seeing problems on other screens, which may fit the activation-safety diagnosis so we'll be looking into that, too. I will keep this thread posted on the result.