Win a copy of The Little Book of Impediments (e-book only) this week in the Agile and Other Processes forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

NX:should lock the database during the creating?

 
ZhiYuan Lin
Ranch Hand
Posts: 44
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
during the creating, i lockRecord(-1) ,because i think the recordCount that is the sum number of record is changed. and it will be used in finding or other places. is it right? or just need to lockRecord(++recordCount)?
 
Mark Spritzler
ranger
Sheriff
Posts: 17278
6
IntelliJ IDE Mac Spring
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
No need to call lock at all in the create method.
Mark
 
Jim Yingst
Wanderer
Sheriff
Posts: 18671
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You probably will need some sort of synchronization during the create process, in case another thread is trying to create a new record at the same time. Otherwise you may have one record overwrite the other, or you might return the incorrect recNo for the record you just created, depending on how you set things up. (Note for Max - even with a just-in-time FileChannel, we'd need the file length to determine recNo, and that length could change immediately before or after an atomic write, right?) Anyway - you probably want some synchronization here; that's not the same thing as record locking. Locking my involve synchronization, but you can also use synchronization without using the lock() and unlock() methods - that's what you need here.
 
ZhiYuan Lin
Ranch Hand
Posts: 44
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
thanks
My createRecord() is synchronized, but i still have some doubt. Because my Data is not single one, it will give a new Data instance for each remote client. If two remote clients create record at same time, use the synchronized can not prevent them from doing it at same time. is it?
 
Jim Yingst
Wanderer
Sheriff
Posts: 18671
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
If two remote clients create record at same time, use the synchronized can not prevent them from doing it at same time. is it?
It depends what they synchronize on - what's used as a monitor? If you synchronize on the client objects, or on the Data instances, then you won't prevent concurrent access. (Individual writes may or may not be atomic, but the space in between doing a write and finding the file length is a problem; you need to prevent another thread from slicing in at that point and changing the file size.) But you could synchronize on some other object, something which is shared amond Data instances. Perhaps an object held by a static variable? My own preference is to have just one FileChannel used by all clients - this makes it easy to just sync on the FileChannel. If you're not doing this - well, I think you need some sort of shared object. Here's one possibility:

Synchronizing on Data.class is a bit ugly - it's one example of an object that any code can share as a monitor, if you want. Many others are possible; some might even be objects that serve some other useful purpose as well.
Max seems to be busy elsewhere at the moment, but I hope he'll post here soon, because I would really like to see some sample code that prevents "dirty creates" while using separate FileChannels, without synchronization. Or maybe dirty creates are considered OK, in the sense that you can guarantee that the data in the file itself is OK, but you may return the wrong value for the record number for what you just created. And our GUI can't do any creates anyway, so maybe we don't need to worry - but I think if we provide a create() method, it should be a create() method that works reliably, even if we don't actually use it.
 
Tony Collins
Ranch Hand
Posts: 435
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I built up a cache and synchronized create/update/read/find methods on the cache. If you hava a singleton Data class or not it makes no difference.
You need to sync on create just in case a thread gets in and writes to the space you've selected to write too. Reads need to be sync'ed to avoid dirty reads, though Max claimed this might be unnecessary as a dirty read is not likely to cause a Run Time Error, as threads making copies of shared resources.
Tony
 
ZhiYuan Lin
Ranch Hand
Posts: 44
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
thanks
hi jim, you say "Synchronizing on Data.class is a bit ugly " but what other is can do it. I have asked should the Data be single one, your answer is no need to do. But, is there something can prevent multiple clients from creating at same time other than synchronizing on Data.class?
I think to lock the database is the one approach.
but i still have one other doubt, during one client reads a record, the other client updates. How to protect my database?( premise : my Data is not single one, it will give a new Data instance for each remote client. )
 
Mark Spritzler
ranger
Sheriff
Posts: 17278
6
IntelliJ IDE Mac Spring
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
: my Data is not single one, it will give a new Data instance for each remote client. )

Actually you want to give each remote client a reference to just one Data instance. The Data class does not and should not be a Singleton Design Pattern. You should just create one instance of this class when you start up the server, then just pass the reference to each client as it connects to the server.
Mark
 
Jim Yingst
Wanderer
Sheriff
Posts: 18671
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
[ZYL]: hi jim, you say "Synchronizing on Data.class is a bit ugly " but what other is can do it.
Well I prefer using a single instance of Data - then you can sync on "this". Or have all the Data instances share a single FileChannel or RandomAccessFile - then you can sync on that. You need some sort of shared object for sync. I suppose Data.class is OK, except that many junior programmers won't recognize the .class syntax for a class literal.
[ZYL]: I have asked should the Data be single one, your answer is no need to do.
Ummm... I forget which conversation this was, but I think I was saying that you probalby shouldn't use the full singleton pattern, which would prevent anyone from ever having additional Data instances, even for other DB files. Personally I strongly prefer that you have one Data instance per db file. Which in practice means you only ever create one Data instance for this assignment. But future enhancements could use other Data instances.
Additionally - well if you really want multiple Data instances, yes it's possible, but you still need something else to sync on during create() at least. (And I really prefer to sync during any update() or delete() as well, and probably read() as well, but there's a long discussion about that...)
[ZYL]: But, is there something can prevent multiple clients from creating at same time other than synchronizing on Data.class?
I think to lock the database is the one approach.

There are some other solutions I can think of that don't involve sync, but all I can think of are signivficantly more complex and/or much slower. Locking the whole DB is probably both. Well, if you have a requirement to be able to lock the whole DE anyway (I don't), then using it here does not really add any complexity. But it is almost certainly slower than simply using sync.
[ZYL]: but i still have one other doubt, during one client reads a record, the other client updates. How to protect my database?( premise : my Data is not single one, it will give a new Data instance for each remote client. )
Options:
  • Syncronize both the read() and update() on some shared monitor object.
  • Rely on the "atomicity" of FileChannel to prevent interference between the read() and write(). I don't believe that FileChannel and associated APIs really guarantee that this will always work, but in practice it certainly seems to work the vast majority of the time at least. This may depend on your platform. See lengthy ongoing discussion here if you want.
  • Accept the possibility that data in a read() may be corrupted (though in practice it seems extremely unlikely)

  • I favor the first option; others here prefer some combination of the other two. I still disagree with the second option, but third is OK, IMO.
    [ August 06, 2003: Message edited by: Jim Yingst ]
     
    Tony Collins
    Ranch Hand
    Posts: 435
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Jim,
    remember you can sync on any static member of the data class.
     
    Jim Yingst
    Wanderer
    Sheriff
    Posts: 18671
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Yup, as noted. ("Perhaps an object held by a static variable?"). Using Data.class was just simplest since I don't have to show any other variable declarations.
     
    Mark Spritzler
    ranger
    Sheriff
    Posts: 17278
    6
    IntelliJ IDE Mac Spring
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    I like the first option too, of synchronizing the methods.
    Mark
     
    ZhiYuan Lin
    Ranch Hand
    Posts: 44
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    O, i got it.
    thank you very much! Mark,Jim,Tony
    hi,Jim thank you for your detailed answer, i will learn the Channel
    hi,Mark I will follow "You should just create one instance of this class when you start up the server, then just pass the reference to each client as it connects to the server." it light me
     
    • Post Reply
    • Bookmark Topic Watch Topic
    • New Topic