Win a copy of Re-engineering Legacy Software this week in the Refactoring forum
or Docker in Action in the Cloud/Virtualization forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

(URLyBird) 1.3.1 reusage of deleted entries

 
Robert Bar
Ranch Hand
Posts: 38
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hello,

Lets assume that record's number (recNo) is simply a record's position in a file, and if recNo equals 0, it refers to the first entry in file. For example: entry with number recNo=N starts at (offset + N*totalRecordSize) position. The second assumption is that create() reuses deleted entries.

Now please, consider following scenarios, where clients work concurrently:

1.

Client A: find(criteriaA) --> result: recNo = 1 (recNo=1 points to dataA)
Client B: delete(recNo = 1)
Client B: create(dataB) --> result: recNo = 1; (now recNo=1 points todataB!)
Client A: read(recNo = 1) --> result: dataB (dataB is a different entry and doesn't have to match criteriaA!)

2.

Client A: lock(recNo = 1) (recNo=1 points to dataA)
Client B: lock(recNo = 1) { recNo=1 exists but is locked --> waiting...}
Client A: delete(recNo = 1)
Client A: unlock(recNo = 1} { notify all...}
Client C: create(dataB) --> result: recNo = 1; (now recNo=1 points to dataB)
Client B: is awaken: checks that recNo=1 exists and locks recNo=1
Client B: delete(recNo = 1) (clientB deleted a dataB, not a dataA!)

In the first scenario ClientA found certian entry matching criteria, but in the meantime ClientB reused this entry and ClientA red someting else!

In the second scenario ClientB wanted to delete dataA at recNo=1, but in the meantime ClientC reused this entry and ClientB deleted something else!

What is your opinion about reusing entries, while each record is identified by its position in file? For me, it leads to serious problems.

Thx,
Rob.
 
Jeroen T Wenting
Ranch Hand
Posts: 1847
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
That's why you should always do a sanity check on a record.
If you're updating something, check that what's in the database is actually what you originally read before the user changed it.
 
Robert Bar
Ranch Hand
Posts: 38
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Jeroen,

you think that there is no sense in locking & updating a record, that has been modified by other client, do you?

ClientA reads data: read(recNo=1)
ClientB reads data: read(recNo=1)
ClientB updates data: detectConcurrentModification(recNo,readBeforeData)-->OK,lock(recNo=1),update(recNo=1),unlock(recNo=1)
ClientA updates data: detectConcurrentModification --> thow an exception

What do you think about checking results of find & read?
During searching int[]find() is followed by String[]read() and I can't guarantee that after find() other client modifies crucial fields. Please, comment this workaround:



BTW. operation String[][] find(String[]) would resolve the problem, but of course no one can change the interface provided by SUN...
[ June 29, 2006: Message edited by: Robert Bar ]
 
Tom Nicki
Greenhorn
Posts: 25
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Robert,

My solution is only theoretical. I havent started implementing yet.
Maybe there is a weekness I haven't thought about.
I am wandering about your opinions.

For me problem does not exist in the database layer. I can simply create class implementing Sun's interface.
For instance imagine 2 oracle sql terminals where I call sql queries and modify the same record. The rule is the last one wins and updates the record.
It is the application above (in a business layer) which shoud take care about transactions, checking if the record i want to modify has been modified in the meantime.
I had 2 separate ideas/solutions:
1. I keep track what clients received by versioning. On the server I store version of each record and I send record always with version to clients. When client calls update I compare 2 versions: version from client and from server. If versions are the same, update is possible. If version is defferent -> exception.
2. I do not allow clients to update. I allow them to "book" which mean "set value of one field". Server just locks a record, checks if it is booked, books it (update one field), and unlocks it. No full update possible - no problem exists

Tom
 
Robert Bar
Ranch Hand
Posts: 38
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Tom,

Originally posted by Tom Nicki:

For me problem does not exist in the database layer. I can simply create class implementing Sun's interface.
Tom

I fully agree.

Originally posted by Tom Nicki:

(...)
Maybe there is a weekness I haven't thought about.
(...)
I had 2 separate ideas/solutions:
(...)
2. I do not allow clients to update. I allow them to "book" which mean "set value of one field". Server just locks a record, checks if it is booked, books it (update one field), and unlocks it. No full update possible - no problem exists
Tom


Second idea works fine, until there is no possibility to delete/create&reuse number. Fortunately, in URLyBird there are no such functionalities.
 
Tom Nicki
Greenhorn
Posts: 25
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Second idea works fine, until there is no possibility to delete/create&reuse number.

Yes. I would have to assume I cannot reuse entries.

Fortunately, in URLyBird there are no such functionalities.

About create/delete.
I have read a few threads where it was written that even if your client program has no create/delete functionality, they should be implemented on the server/database side (and tested well).
I think problem still exists. Proper implementation and a strong argumentation is needed.

Tom
 
Jeroen T Wenting
Ranch Hand
Posts: 1847
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
client A reads record
client B reads record
client A locks record
client A reads record
client A updates record
client A unlocks record
client B locks record
client B reads record
client B notices record is changed on disk and asks user for confirmation to update
client B either updates record or not depending on user input
client B unlocks record

That's my application flow in case a record is changed on disk after being initially read.
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic