Icon View Thread

The following is the text of the current message along with any replies.
Messages 11 to 16 of 16 total
Thread Flushbuffers in a multiuser environment
Wed, Apr 16 2014 6:43 AMPermanent Link

Markus Gnam

Hello Roy,

yes, one reason is trying to prevent data corruption. I've had an "Unknown error when altering table" recently with version 4.38 build 1. I've updated now to version 4.38 build 2 because this build contains a fix for the German local issue (# 4026 ) which might have caused corruption.

More importantly, I want to ensure that every user sees the most recently changed values by other users in a multi user environment. Every user in a multi user environment should see the up-todate values as soon as possible.

However, I'm not shure if FlushBuffers can enable this. It seems the Windows operating system doesn't save immediately to disk although when calling FlushBuffers. I haven't noticed big differences when calling FlushBuffers or not calling it until now (concerning behaviour and performance), but I have tested only a few days. I will keep an eye on it.

Best wishes,
Markus
Wed, Apr 16 2014 7:39 AMPermanent Link

Roy Lambert

NLH Associates

Team Elevate Team Elevate

Markus

>yes, one reason is trying to prevent data corruption. I've had an "Unknown error when altering table" recently with version 4.38 build 1. I've updated now to version 4.38 build 2 because this build contains a fix for the German local issue (# 4026 ) which might have caused corruption.

That one I can't even begin to help with, but I would guess that flushing the buffers wouldn't help.

>More importantly, I want to ensure that every user sees the most recently changed values by other users in a multi user environment. Every user in a multi user environment should see the up-todate values as soon as possible.
>
>However, I'm not shure if FlushBuffers can enable this. It seems the Windows operating system doesn't save immediately to disk although when calling FlushBuffers. I haven't noticed big differences when calling FlushBuffers or not calling it until now (concerning behaviour and performance), but I have tested only a few days. I will keep an eye on it.

This is a question that's often asked.

It can't. Flushing the data down to disk isn't suddenly going to make it appear on other people's screens. Sad but true Frown

Even sadder suggesting a move to client server wouldn't help either.

You have a couple of options:

1. Do a table refresh using a timer
2. Come up with a signalling method between the various users of the software - since you're using file sharing UPD might work

No. 1 is by far the easier option to go with and can be more efficient than the signalling approach depending on frequency of data change.

Not knowing the layout and organisation of your app or frequency of data change I can't suggest how often to do this so I'd suggest a user settable parameter. Depending on the controls used you may have to refresh those as well to ensure they're updated with the latest contents.

Make sure (set a flag in the BeforeEdit event) that you don't try and refresh a table that's in insert or edit mode.

I think a refresh will get the data even if held in buffer but I'm sure Tim will correct me if I'm wrong.

Option 2. can be made to work well. One approach as I've said above is to use UDP (I'd suggest Synapse) and have a listener built into your app. Another approach is to use TCP/IP and send messsages directly to the app knowing its address on the LAN. One the message is received by whatever means you simply do a table.Refresh

You can come up with all sorts of variations on the above two basic concepts eg a refinement of No. 1 is to have a table which simply records that an alteration has been made to one of the table in the application. That one is checked say twice a second in a background thread (minimises the impact on the app) and only is an alteration has been made to a specific table does it signal the main thread to carry out a refresh.

Roy
Wed, Apr 16 2014 9:15 AMPermanent Link

Markus Gnam

Thank you Roy, for these great considerations, especially your ideas concerning "Refresh".
Maybe I should add one more Detail: The table contains about 6 million records. The most important part of the application is a call of "Findnearest" to jump to the next index entry to work with. It seems that simply a call of "Refresh" BEFORE the call of "Findnearest" helps a lot.

I have to test this more, also if FlushBuffers is still needed. I will consider all your other very helpful hints, too. Thank you again, I appreciate it.

Best wishes,
Markus
Wed, Apr 16 2014 11:30 AMPermanent Link

Roy Lambert

NLH Associates

Team Elevate Team Elevate

Markus

>Thank you Roy, for these great considerations, especially your ideas concerning "Refresh".
>Maybe I should add one more Detail: The table contains about 6 million records. The most important part of the application is a call of "Findnearest" to jump to the next index entry to work with. It seems that simply a call of "Refresh" BEFORE the call of "Findnearest" helps a lot.

Can you explain the FindNearest a bit more, I found that there are better ways generally eg using a second cursor to the table with a filter and then a Locate or FindKey.

Roy
Thu, Apr 17 2014 3:16 AMPermanent Link

Markus Gnam

Hello Roy,

my use of FindNearest is a bit complicated to explain. I think I'll create a new thread about it. I don't have problems with FindNearest but it's an very interesting topic. Thank you!

Best wishes,
Markus
Mon, Apr 28 2014 11:10 AMPermanent Link

Tim Young [Elevate Software]

Elevate Software, Inc.

Avatar

Email timyoung@elevatesoft.com

Markus,

<< However, when iterating through a dataset with a while loop, calling
Flushbuffers in the afterpost event seems to slow performance signifcantly
down. Therefore, when executing while loops I don't call Flushbuffers (of
course in this case this is a single user environment with exclusive opening
of the table). >>

You can just call FlushBuffers after the loop.  There's a small window of
opportunity for corruption while the loop is executing, but as long as the
total execution time for the loop is relatively small, then you should be
okay.

But, the *best* way to ensure that you don't have any issues is to use a
transaction for the loop, and make sure that you allow DBISAM to perform a
default Commit with a flush to disk (ForceFlush=True):

http://www.elevatesoft.com/manual?action=viewmethod&id=dbisam4&product=delphi&version=7&comp=TDBISAMDatabase&method=Commit

Tim Young
Elevate Software
www.elevatesoft.com
« Previous PagePage 2 of 2
Jump to Page:  1 2
Image