How to prevent a user from deleting a record while another is edi ting it 2004-09-28 - By Nicholas Wee
Back Hello,
I agree that the requirement is rather strange, i.e. to deny delete if someone is modifying, in a multi-tiered system, but totally permissible given what I seen users ask for :).
In a multi-tiered system, our normal practice in handling a race condition is to use a version field (of type long integer) to control concurrent updates. So, an additional WHERE condition is used to check that the record in buffer (such as in HTTP Session) that was retrieved earlier for display to the user for the update (or delete) transaction has the same version number as in the database. Otherwise, the update (or delete) transaction is denied with an exception. And in that same SQL transaction, the version number is also incremented. E.g UPDATE TableA SET A='XYZ', SET VER_NUM = VER_NUM + 1 WHERE VER_NUM = BUF_VER_NUM;.
Also, in our practice, records in the database are never really deleted...but rather are marked for deletion using an additional field, e.g. IS_DELETED, that acts as a flag. Then using a housekeeping job, these marked records are archieved out of the system.
But I digress, and coming back to this requirement...a solution may be to add an addition field, e.g. IS_MODIFYING, to flag that a record has been retrieved for update. This is set on, and the version number is incremented (in the same transaction). Then any subsequent retrieval, including those for delete will know that a record has been marked for editing or modification. Then, when the update completes, this flag can be set off. However, I think you will need a housekeeping job to clear flags automatically at the end of a business day (for example), and an administrative transaction to manually clear such flags for 'urgent' cases. These are to handle situations where the browser performing the modifications is terminated for whatever reasons.
Just my suggestion.
Regards Nicholas
Gerard Toonstra <toonstra@(protected)> wrote: Although the timestamp approach is somehow valid, I think the requirement is very strange. The requirement to me re-reads as:
"Normally we would allow a user to delete the data, *except* when someone else is just about to modify it."
That doesn't really make sense to me. What makes more sense to me is:
"When you are editing data that someone else has deleted in the meantime, the application will return an error."
How many seconds should elapse after the timestamp before the record *may* be deleted by someone else? It is possible that someone starts to modify the data, then goes on doing something completely different. Person B then cannot delete the data until X minutes expire and this original requirement thereby causes more frustration then it does good. Does this time need to be configurable as well??? ..... ->>
The cause is that something recording the start of a particular transaction is not as volatile as the transaction itself and is fully detached from that transaction.
I would solve this requirement differently, but it requires more effort:
1. Do a lookup of the data. 2. Present the data to the user. Are you sure you want to delete the data as you see it on screen? 3. If yes, record a delete request in a table, together with a version identifier of the data "as it is seen". ( use timestamp here? ). 4. Delete the data X hours later from a batch process, when no intermediate updates have occurred ( timestamp > recorded version timestamp ).
If the data is then *actually* modified before these X hours, the data will not be deleted. Otherwise it goes to the trashbin. Having said all this, it's definitely preferable to do something simpler or not anything at all :)
The simplest approach is for the modify action to delete all outstanding delete requests as it updates data. No timestamp is then needed. Just record when the delete request is created for the batch process 24 hours later.
About the modification process:
I haven't seen other responses as I am new to the list, but I think in any case, the "old" data is needed by the update operation.
There are possibly several approaches from there, like:
1. Lock the row in question you wish to update. 2. Select the data again as it is now just before the update. 3. Verify it's the same as what you have in the old data object. 4. Perform the update, set data to "new". 5. Commit.
or update the row directly:
UPDATE A SET X = where Y = and X = ( and.... z.current = z.old .... )
If no updates have occurred, apparently it has been edited inbetween the old retrieval and the new update. The update result will then returns 0 rows updated.
The user will then normally be sent back to the beginning and has to do everything again. Only rarely do I see applications where the new data is shown and a confirmation is requested whether the user really wants to overwrite the new current date with the new data previously entered.
Just 2c,
Gerard
At 02:21 28/9/2004, you wrote: >Hi, >Another is editing means somebody is using the modify / update page. >SO, u can insert a timestamp in the table when ever u use this table in >modify mode. >Whenever u select the data frm this table get this timestamp also. Then when >u need to update the DB only if the selected and the current timestamp in >that column is equal. > >Otherwise what u r doing is updating the data which is not the correct >version which u wanna to be. > >This is called Version Control pattern. > >Regards, >Manish > > >-- --Original Message-- -- >From: An interest list for Sun Java Center J2EE Pattern Catalog >[mailto:J2EEPATTERNS-INTEREST@(protected)]On Behalf Of Gupta, Rajan >Sent: Sunday, September 05, 2004 9:49 AM >To: J2EEPATTERNS-INTEREST@(protected) >Subject: How to prevent a user from deleting a record while another is >edi ting it > > >I am looking for a pattern for CMP based persistence model under EJB 2.0 >which will prevent a user to delete a record while another is editing it. > >Thanks in advance, >Rajan
==================================================================== Companion Site: http://www.corej2eepatterns.com J2EE BluePrints: http://java.sun.com/blueprints/corej2eepatterns List Archive: http://archives.java.sun.com/archives/j2eepatterns-interest.html Unsubscribing: email "signoff J2EEPATTERNS-INTEREST" to listserv@(protected)
-- ---- ---- ---- ---- ---- ----- Do you Yahoo!? vote.yahoo.com - Register online to vote today!
==================================================================== Companion Site: http://www.corej2eepatterns.com J2EE BluePrints: http://java.sun.com/blueprints/corej2eepatterns List Archive: http://archives.java.sun.com/archives/j2eepatterns-interest.html Unsubscribing: email "signoff J2EEPATTERNS-INTEREST" to listserv@(protected) <DIV>Hello,</DIV> <DIV> </DIV> <DIV>I agree that the requirement is rather strange, i.e. to deny delete if someone is modifying, in a multi-tiered system, but totally permissible given what I seen users ask for :).</DIV> <DIV> </DIV> <DIV>In a multi-tiered system, our normal practice in handling a race condition is to use a version field (of type long integer) to control concurrent updates. So, an additional WHERE condition is used to check that the record in buffer (such as in HTTP Session) that was retrieved earlier for display to the user for the update (or delete) transaction has the same version number as in the database. Otherwise, the update (or delete) transaction is denied with an exception. And in that same SQL transaction , the version number is also incremented. E.g UPDATE TableA SET A='XYZ', SET VER_NUM = VER_NUM + 1 WHERE VER_NUM = BUF_VER_NUM;.</DIV> <DIV> </DIV> <DIV>Also, in our practice, records in the database are never really deleted.. .but rather are marked for deletion using an additional field, e.g. IS_DELETED, that acts as a flag. Then using a housekeeping job, these marked records are archieved out of the system.</DIV> <DIV> </DIV> <DIV>But I digress, and coming back to this requirement...a solution may be to add an addition field, e.g. IS_MODIFYING, to flag that a record has been retrieved for update. This is set on, and the version number is incremented (in the same transaction). Then any subsequent retrieval, including those for delete will know that a record has been marked for editing or modification. Then, when the update completes, this flag can be set off. However, I think you will need a housekeeping job to clear flags automatically at the end of a business day (for example), and an administrative transaction to manually clear such flags for 'urgent' cases. These are to handle situations where the browser performing the modifications is terminated for whatever reasons.</DIV> <DIV> </DIV> <DIV>Just my suggestion.</DIV> <DIV> </DIV> <DIV>Regards</DIV> <DIV>Nicholas<BR><BR><B><I>Gerard Toonstra <toonstra@(protected)></I></B> wrote:</DIV> <BLOCKQUOTE class=replbq style="PADDING-LEFT: 5px; MARGIN-LEFT: 5px; BORDER -LEFT: #1010ff 2px solid">Although the timestamp approach is somehow valid, I think the requirement<BR>is very strange. The requirement to me re-reads as:<BR ><BR>"Normally we would allow a user to delete the data, *except* when someone <BR>else is just about to modify it."<BR><BR>That doesn't really make sense to me. What makes more sense to me is:<BR><BR>"When you are editing data that someone else has deleted in the meantime,<BR>the application will return an error."<BR><BR><BR>How many seconds should elapse after the timestamp before the record<BR>*may* be deleted by someone else? It is possible that someone starts to modify<BR>the data, then goes on doing something completely different . Person B then<BR>cannot delete the data until X minutes expire and this original requirement<BR>thereby causes more frustration then it does good. Does this time need to be<BR>configurable as well??? ..... ->><BR><BR>The cause is that something recording the start of a particular transaction is<BR>not as volatile as the transaction itself and is fully detached from that<BR>transaction.<BR><BR><BR>I would solve this requirement differently, but it requires more effort:<BR><BR>1. Do a lookup of the data.<BR>2. Present the data to the user. Are you sure you want to delete the data<BR>as you<BR>see it on screen?<BR>3. If yes, record a delete request in a table, together with a version<BR>identifier of<BR>the data "as it is seen ". ( use timestamp here? ).<BR>4. Delete the data X hours later from a batch process, when no intermediate<BR>updates<BR>have occurred ( timestamp > recorded version timestamp ).<BR><BR>If the data is then *actually* modified before these X hours, the data will<BR>not be deleted.<BR>Otherwise it goes to the trashbin. Having said all this, it's definitely<BR>preferable<BR>to do something simpler or not anything at all :)<BR><BR>The simplest approach is for the modify action to delete all outstanding delete<BR>requests as it updates data. No timestamp is then needed.<BR>Just record when the delete request is created for the batch process 24<BR>hours later.<BR><BR><BR>About the modification process:<BR><BR>I haven't seen other responses as I am new to the list, but I think in any<BR>case,<BR>the "old" data is needed by the update operation.<BR><BR>There are possibly several approaches from there, like:<BR> <BR>1. Lock the row in question you wish to update.<BR>2. Select the data again as it is now just before the update.<BR>3. Verify it's the same as what you have in the old data object.<BR>4. Perform the update, set data to "new".<BR>5. Commit.<BR><BR>or update the row directly:<BR><BR>UPDATE A SET X = <NEW>where Y = <KEY>and X = <OLD>( and.... z.current =<BR>z.old .... )<BR><BR>If no updates have occurred, apparently it has been edited inbetween the<BR>old retrieval and <BR>the new update. The update result will then returns 0 r ows updated.<BR><BR>The user will then normally be sent back to the beginning and has to do<BR>everything again.<BR>Only rarely do I see applications where the new data is shown and a<BR>confirmation is requested<BR>whether the user really wants to overwrite the new current date with the<BR>new data previously entered .<BR><BR>Just 2c,<BR><BR>Gerard<BR><BR><BR>At 02:21 28/9/2004, you wrote:<BR>> ;Hi,<BR>>Another is editing means somebody is using the modify / update page. <BR>>SO, u can insert a timestamp in the table when ever u use this table in <BR>>modify mode.<BR>>Whenever u select the data frm this table get this timestamp also. Then when<BR>>u need to update the DB only if the selected and the current timestamp in<BR>>that column is equal.<BR>><BR>> ;Otherwise what u r doing is updating the data which is not the correct<BR>> ;version which u wanna to be.<BR>><BR>>This is called Version Control pattern.<BR>><BR>>Regards,<BR>>Manish<BR>><BR>><BR>>---- -Original Message-- --<BR>>From: An interest list for Sun Java Center J2EE Pattern Catalog<BR>>[mailto:J2EEPATTERNS-INTEREST@(protected)]On Behalf Of Gupta, Rajan<BR>>Sent: Sunday, September 05, 2004 9:49 AM<BR>>To: J2EEPATTERNS-INTEREST@(protected)<BR>>Subject: How to prevent a user from deleting a record while another is<BR>>edi ting it<BR>><BR>><BR>>I am looking for a pattern for CMP based persistence model under EJB 2.0<BR>> ;which will prevent a user to delete a record while another is editing it.<BR> ><BR>>Thanks in advance,<BR>>Rajan<BR><BR>============================= =======================================<BR>Companion Site: http://www .corej2eepatterns.com<BR>J2EE BluePrints: http://java.sun.com/blueprints /corej2eepatterns<BR>List Archive: http://archives.java.sun.com/archives /j2eepatterns-interest.html<BR>Unsubscribing: email "signoff J2EEPATTERNS -INTERES T" to listserv@(protected)<BR></BLOCKQUOTE><p> <hr size=1>Do you Yahoo!?<br><a href="http://vote.yahoo.com">vote.yahoo.com</a> - Register online to vote today! ==================================================================== Companion Site: http://www.corej2eepatterns.com J2EE BluePrints: http://java.sun.com/blueprints/corej2eepatterns List Archive: http://archives.java.sun.com/archives/j2eepatterns-interest.html Unsubscribing: email "signoff J2EEPATTERNS-INTEREST" to listserv@(protected)
|
|