Download sample application - RowLockingApp.zip. This sample contains one ADF task flow based on JSF fragments. Default activity represents read-only table with Employees data. When user hits employee editing button, navigation is passed to Method Call activity - it invokes method from Application Module Implementation class to lock current record from Employees VO. If current record is not locked by another user - lock is set and editing screen opens successfully. Otherwise, if current record is already locked by another user - we render information message and display data in read-only mode:
Immediate row locking mechanism is implemented by overriding AM and EO implementation classes:
Custom row locking method from AM implementation class is exposed through client interface:
This method retrieved current row from VO and invoked VO lock method. If current row is already locked by another user or lock fails, we catch exception and return negative parameter value into Controller layer:
If current row is already locked, we want to render it in read-only mode. This can be achieved by overriding isAttributeUpdateable(int i) method from EO implementation class. If attempt to lock current record failed, this means user can't edit any attributes - read-only mode:
Controller layer receives result of locking method from AM implementation class and stores into Page Flow Scope:
This value is used to render or not information message about failed locking attempt:
Rendered property is referencing value from Page Flow Scope:
If current row was not locked by another user and current user performs successful lock - lock will remain until user will commit or rollback his changes for current row. Its almost true, but not completely. What will happen if user will close browser without performing commit/rollback or even without doing proper logout action? Good news - obtained lock will be removed automatically, after web session times out. After web session time out, database connection still will remain open and can be reused by another AM instances. However current web session AM instance will be destroyed, this means database lock obtained by that session also will be removed. This means if user will forget to commit/rollback or logout, longest time when current row will remain locked is equal to web session time out time. You should keep this in mind, when configuring and tuning your ADF 11g application. Default web session time out - 30 minutes is sufficient in most of the cases.
In order to test locking behavior, I have set web session timeout to 5 minutes:
Let's experiment a bit and see how it works. User A logs in into application and opens Employees list screen:
User A select record and opens it for editing, lock is applied automatically:
We can see from the log, lock is successful for user A:
Another user B selects the same record:
And opens it for editing, however same record is already locked by user A - lock for user B fails and data is rendered in read-only mode with information message:
Lock for user B fails:
Lock from user A will remain until commit/rollback or logout. Let's say user A will not do any of mentioned actions and just will leave from his work place by closing browser or keeping it open. Two sessions, one for user A and another for user B are active:
Because of inactivity, user A session will timeout after 5 minutes (as it is set in web.xml) and AM instance will be released:
When user A will return to check his work, he will receive session timeout message and will be forced to login again - of course lock will be lost:
Next release of ADF 11g - PS3 provides user-friendly popup message for session timeout.
After waiting 5 minutes (session timeout for user A), user B will be able to lock released record and perform required changes:
Custom row locking method from AM implementation class is exposed through client interface:
This method retrieved current row from VO and invoked VO lock method. If current row is already locked by another user or lock fails, we catch exception and return negative parameter value into Controller layer:
If current row is already locked, we want to render it in read-only mode. This can be achieved by overriding isAttributeUpdateable(int i) method from EO implementation class. If attempt to lock current record failed, this means user can't edit any attributes - read-only mode:
Controller layer receives result of locking method from AM implementation class and stores into Page Flow Scope:
This value is used to render or not information message about failed locking attempt:
Rendered property is referencing value from Page Flow Scope:
If current row was not locked by another user and current user performs successful lock - lock will remain until user will commit or rollback his changes for current row. Its almost true, but not completely. What will happen if user will close browser without performing commit/rollback or even without doing proper logout action? Good news - obtained lock will be removed automatically, after web session times out. After web session time out, database connection still will remain open and can be reused by another AM instances. However current web session AM instance will be destroyed, this means database lock obtained by that session also will be removed. This means if user will forget to commit/rollback or logout, longest time when current row will remain locked is equal to web session time out time. You should keep this in mind, when configuring and tuning your ADF 11g application. Default web session time out - 30 minutes is sufficient in most of the cases.
In order to test locking behavior, I have set web session timeout to 5 minutes:
Let's experiment a bit and see how it works. User A logs in into application and opens Employees list screen:
User A select record and opens it for editing, lock is applied automatically:
We can see from the log, lock is successful for user A:
Another user B selects the same record:
And opens it for editing, however same record is already locked by user A - lock for user B fails and data is rendered in read-only mode with information message:
Lock for user B fails:
Lock from user A will remain until commit/rollback or logout. Let's say user A will not do any of mentioned actions and just will leave from his work place by closing browser or keeping it open. Two sessions, one for user A and another for user B are active:
Because of inactivity, user A session will timeout after 5 minutes (as it is set in web.xml) and AM instance will be released:
When user A will return to check his work, he will receive session timeout message and will be forced to login again - of course lock will be lost:
Next release of ADF 11g - PS3 provides user-friendly popup message for session timeout.
After waiting 5 minutes (session timeout for user A), user B will be able to lock released record and perform required changes:
Hi, I was trying your sample application. But it asked for a login for jazn.com when I ran the application. What is the login to use the application?
ReplyDeleteThanks,
Also, I've tried the suggestion in my own application and couldn't get it to work.
my code:
if (groupEO.isLocked()){
throw new Exception("already locked");
}
else{
try{
groupEO.lock();
}
catch(Exception e){
throw new Exception("lock failed");
}
}
What I observed is that when session A entered the lock, groupEO.lock() succeeded and groupEO.isLocked() returned true after the lock() call (was false before). But when session B entered the method, groupEO.isLocked() was false instead of true and it went ahead and executed lock() successfully. Appears that the two locks aren't the same lock.
Yes of course, you must run it with ADF Security enabled. See jazn-data.xml, there is default user redsam/welcome1 defined.
ReplyDeleteAndrejus
Hi! first congratulation for the blog. I was trying to implemet lock in my application. Lock work correctly only if i set a breakpoint into isAttributeUpdateable methods. If i run application without breakpoint the page is always locked. why? thanks a lot
ReplyDeleteI was trying to implemet lock in my application. Lock work correctly only if i set a breakpoint into isAttributeUpdateable methods. If i run application without breakpoint the page is always locked. why? thanks a lot
ReplyDelete