• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

NX: URLyBird - Data Access

 
Ranch Hand
Posts: 4982
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
From the instruction, we know that:
You may assume that at any moment, at most one program is accessing the database file.
How should I interpret it?
1. Only 1 thread can access the file at one time even with multiple requests?
OR
2. Multiple requests can call same read (for example) method, and they worked concurrently?
If it is case 2, then, even a read only request, I need that thread to get a lock before read? Since different threads can call raf.seek(pos), and if:
thread1: raf.seek(100);
thread2: raf.seek(200);
thread1: raf.read();
then, this results in an inconsisent read!!
Thanks
 
Ranch Hand
Posts: 91
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Nicholas Cheung:
...
How should I interpret it?
1. Only 1 thread can access the file at one time even with multiple requests?
OR
2. Multiple requests can call same read (for example) method, and they worked concurrently?
...
then, this results in an inconsisent read!!



Hi Nicholas,
From reading your two interpretations of the specification, I'd say they are both correct -- perhaps I am misunderstanding your meaning. Concerning the first, at most one client thread can access the file at one time (even with multiple concurrent requests). The (single) server thread will force all clients to stand in line and serve each client data one at a time. Concerning the second, multiple client threads can concurrently call the same read method (for example) of your DBAccess class, but you'll need to find a way to handle the requests so that each one takes its turn accessing the file, one at a time.
Concerning your inconsistent read issue, if you force multiple threads to "stand in line" and access the file one at a time, resetting the file pointer every time your read operation is invoked should prevent that problem.
Regards,
Paul
[ November 13, 2003: Message edited by: Paul Tongyoo ]
[ November 13, 2003: Message edited by: Paul Tongyoo ]
 
Nicholas Cheung
Ranch Hand
Posts: 4982
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I get what you mean.
In addition, I would like to ask:
1. Do I need to handle dirty read?
i.e. When a thread writes to record X, while another thread reads the record X. Should I prevent this?
2. I read some previous posts that the system has a "DATABASE LOCK", which locks the whole DB file. Should I need this? (in order to prevent dirty read/write)
3. If I have a wrapper class, say RecordHandler.
It has the same method as what defined in Data.java as well as DBMain.java (the interface given by Sun), but I put the keyword "synchronized" in front of each function, does this suitable? or it violates the spec. from SUN?
Since synchronizing the access (read/write) makes sure that there will not be dirty read/write.
Thanks a lot.
 
Paul Tongyoo
Ranch Hand
Posts: 91
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Nicholas Cheung:
...
1. Do I need to handle dirty read?
i.e. When a thread writes to record X, while another thread reads the record X. Should I prevent this?
2. I read some previous posts that the system has a "DATABASE LOCK", which locks the whole DB file. Should I need this? (in order to prevent dirty read/write)
3. If I have a wrapper class, say RecordHandler.
It has the same method as what defined in Data.java as well as DBMain.java (the interface given by Sun), but I put the keyword "synchronized" in front of each function, does this suitable? or it violates the spec.



You definitely are on the right track - I'd say that the answer to all three of your questions revolve around the same solution which you touch upon in your third question. I'll just answer your easy question in number 3 -- as long as you don't change Sun's interface you're not violating its specs. I myself extended DBMain to include another operation and then had Data.java implement an ExtendedDBMain interface instead. This should still allow my Data class to be tested by Sun's auto-test procedures because the the class will still adhere to the interface (functionality) of a DBMain object.

Regards,
Paul
 
Ranch Hand
Posts: 493
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hello Paul,
You wrote:


I myself extended DBMain to include another operation and then had Data.java implement an ExtendedDBMain interface instead. This should still allow my Data class to be tested by Sun's auto-test procedures because the the class will still adhere to the interface (functionality) of a DBMain object.


I have the same DBMain interface that you have. In order to be closer to Sun's specs and eliminate any doubts whatsoever, I let the Data class implement the Sun supplied DBMain interface. I even kept the interface unchanged, i.e., did not bother to pretty it up using MY JavaDoc comments etc. in my submission. I needed at least one more public method, I called it getColumnNames, in the Data class however, to get the column headers for the UI. To accommodate it, I ended up creating another interface I called DBMainExtended (you call it ExtendedDBMain, same thing really). DBMainExtended is implemented by the DataAdapter class in my implementation and not the Data class. DataAdapter class, as the name suggests, simply ADAPTS the Data class. That is, it has a reference to it as a private Data instance variable and matching wrapper methods for each public method. The DataAdapter class method calls simply route the calls to the matching Data class method. By doing this, I have followed the spec 100% (at least for this requirement!). Logically, what you are doing is the same thing, but I am not sure how will Sun's automated testing process works.
A comment for Nicholas: What you want to think about to prevent dirty reads/writes (or more correctly, inconsistent reads/writes) is to: 1. Use a single instance of the file-pointer doing read/write instead of multiple pointers, and 2. Synchronize the read/write operations to the file so that an ENTIRE record including the delete flag is read/written in one fell-swoop. For example, the readFully method of RandomAccessFile allows you to read an entire byte array and also blocks while the array is being read. If you do this within a synchronized block on RAF then you avoid the aforementioned inconsistency problem.
Hope this helps.
Regards.
Bharat
 
Paul Tongyoo
Ranch Hand
Posts: 91
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Bharat Ruparel:
...I needed at least one more public method, I called it getColumnNames, in the Data class however, to get the column headers for the UI. To accommodate it, I ended up creating another interface I called DBMainExtended (you call it ExtendedDBMain, same thing really). DBMainExtended is implemented by the DataAdapter class in my implementation and not the Data class...



Hi Bharat-- thank you for commenting on my design. Do you suggest that I keep my Data class implementing the DBMain interface only and move the "extra implementation code" of my ExtendedDBMain interface to my DataAdapter class? I will definitely look into this-- keeping my Data class implementing DBMain only would be alot safer since I do not know anything about Sun's testing procedures either. Thanks for the tip!

Regards,
Paul
 
Bharat Ruparel
Ranch Hand
Posts: 493
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hello Paul,
You wrote:


Do you suggest that I keep my Data class implementing the DBMain interface only and move the "extra implementation code" of my ExtendedDBMain interface to my DataAdapter class?


Yes. That is what I am suggesting. Safer alternative in my opinion.
Regards.
Bharat
 
Paul Tongyoo
Ranch Hand
Posts: 91
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Actually, I think i'm going to stay with my augmented Data class interface; my getMetaData(DBAccessor db) operation (the added op) needs my DBAccessor object (my low-level data-file accessing object) to create a new MetaData object and I don't want to expose DBAccessor above the Data class level. Having read some posts in this forum, I believe extending the DB interface should be okay.
I'd appreciate hearing from anyone if they've gotten marked down for extending the DB interface though!!!

Regards,
Paul
 
Nicholas Cheung
Ranch Hand
Posts: 4982
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks Pual and bharat for asking my doubts.


1. Use a single instance of the file-pointer doing read/write instead of multiple pointers, and
2. Synchronize the read/write operations to the file so that an ENTIRE record including the delete flag is read/written in one fell-swoop.


At first, I define the RandomAccessFile(raf) at instance level.
But then, I found the data consistency problem occurs.
So, for each I/O function, I let them to have their own RAF, and remove
the instance RAF, becos, as local variable, one seek() does not affect another seek(). Does this work?
In addition, how should I synchronize the read/write operation? could you explained it more detail?
e.g., for each read/write(), I do the following:

Does this what u mean?
Thanks
 
Bharat Ruparel
Ranch Hand
Posts: 493
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hello Nicholas,
Sorry, didn't respond to your question sooner. I have Singleton class called DataSchema that is used by ALL instances of the Data class. I open the RAF in DataSchema class upon the first call and it stays open until I shut the server down. Therefore, the same instance of the RAF is being used by all instances of the Data class. You may want to do something similar.
Your code block looks fine to me, i.e., you should be synchronizing on the the instance of the RAF as your code shows.
Regards.
Bharat
 
Don't sweat petty things, or pet sweaty things. But cuddle this tiny ad:
a bit of art, as a gift, the permaculture playing cards
https://gardener-gift.com
reply
    Bookmark Topic Watch Topic
  • New Topic