If you are familiar with how the database command line works
you know that you can insert or update rows in the database and until you
commit, no one else accessing the system will see your changes until you commit
them. You can update a row, insert a
row, delete a row and then re-query the tables you’ve changed and you will see
your changes but no one else will. This
relates to the isolation transactional property of the ACID (Atomicity, Consistency, Isolation, Durability) features of modern databases. You should not use the feature in a web
application because you should never post data without immediately following up
with a commit in the same request. Since
the request is coming from a web page if you were to post without committing
you run the risk of never completing the commit and leaving the table with
locked rows.
In ADF this problem is solved using the Entity Cache. We can think of the Entity cache as a work area containing pending changes but the changes do not hold a lock in the database. The cache adds an additional layer between the database session and the pending changes. These pending changes never get posted to the database until a commit is performed. In addition when you run a entity based query, after executing the query, the framework will look in the Entity cache to see if any of the rows returned have pending changes and will merge the pending changes with the results just retrieved. This simulates the behavior of a post without a commit. Only the specific user sees their own pending changes but it does this without ever posting the changes so no lock is created on the table (Assuming jbo.locking.mode is set to the default optimistic setting not pessimistic).
The entity cache allows one view object to display uncommitted rows that were updated in another view object (within the same application module) that is using one or more of the same entities. It also allows changes to be propagated across these view objects without ever communicating with the database. For example, if the user updates a UI field linked to one view object and somewhere else on the page, a different view object using that same entity is displaying that value, All you need to do is refresh that other part of the page and you will see the pending change.
In ADF this problem is solved using the Entity Cache. We can think of the Entity cache as a work area containing pending changes but the changes do not hold a lock in the database. The cache adds an additional layer between the database session and the pending changes. These pending changes never get posted to the database until a commit is performed. In addition when you run a entity based query, after executing the query, the framework will look in the Entity cache to see if any of the rows returned have pending changes and will merge the pending changes with the results just retrieved. This simulates the behavior of a post without a commit. Only the specific user sees their own pending changes but it does this without ever posting the changes so no lock is created on the table (Assuming jbo.locking.mode is set to the default optimistic setting not pessimistic).
The entity cache allows one view object to display uncommitted rows that were updated in another view object (within the same application module) that is using one or more of the same entities. It also allows changes to be propagated across these view objects without ever communicating with the database. For example, if the user updates a UI field linked to one view object and somewhere else on the page, a different view object using that same entity is displaying that value, All you need to do is refresh that other part of the page and you will see the pending change.
Every entity has its own entity cache. The cache will contain rows to update, rows
to add and rows to delete for a single table.
When it is time to commit, the framework simply has to look in the
entity caches, post each entity change and then perform a single commit.
Because the rows were not locked, it is possible that another user or process could have updated the same row. The framework will compare the original values that are also stored in the entity cache with the values currently in the database and if they differ you will get an error "JBO-25014: Another user has changed the row with primary key oracle.jbo.Key". Also see yet-another-reason-for-jbo-25014.
There is a lot more to the entity cache but hopeful this simple explanation will help. For more in-depth information on the Entity Cache See
Because the rows were not locked, it is possible that another user or process could have updated the same row. The framework will compare the original values that are also stored in the entity cache with the values currently in the database and if they differ you will get an error "JBO-25014: Another user has changed the row with primary key oracle.jbo.Key". Also see yet-another-reason-for-jbo-25014.
There is a lot more to the entity cache but hopeful this simple explanation will help. For more in-depth information on the Entity Cache See
Nice Post :)
ReplyDeleteGood explanation with correlation to database.
ReplyDeleteDoes the same apply to delete as well ? Lets say one removed the row from a Rowset in one VO and accessed another instance of the same VO from another method .. Will he be able to see the deleted row ??
ReplyDeleteThe deleted row should be gone from both view objects as long as they both are coming from the same application module instance. You may need to trigger a refresh on the other view object.
ReplyDelete