Login ProductsSalesSupportDownloadsAbout |
Home » Technical Support » DBISAM Technical Support » Support Forums » DBISAM General » View Thread |
Messages 1 to 10 of 11 total |
Confused: Error 8708 Record has been changed or deleted by another user |
Tue, Feb 27 2007 4:33 PM | Permanent Link |
Sam Davis | I'm getting this error message and I know why, but ...
Here's what's happening. My Delphi app is running and has gone and added 10 rows to a table. After the loop has completed, I go over to DSU and delete the 10 rows because I want to rerun the test. I rerun the test (my program hasn't closed) and my routine instantiates a TDBISAMTable and connects to the database. This table then does a FindKey and it finds the deleted record!? Why? The record is gone. Since it finds the record it then tries to put it into Edit mode and that's when I get the error "#8708-Record has been changed or deleted by another users...". So why doesn't TDBISAMTable know that the rows in the table have been deleted? What am I doing wrong? I currently have StrictChangeDetection set to False (default). TIA Sam |
Tue, Feb 27 2007 8:02 PM | Permanent Link |
Jose Eduardo Helminsky | Sam
It is a matter of buffers thing. Your application instantiate one TDBISamTable. The DBSys instantiate other (of course) and when you delete the records, the instance created inside your application doesn´t know if they were deleted. You need to apply a Refresh method inside your application just before you want to rerun the tests. Another thing you can do is set StrictChangeDetection to True and DBISAM always check if the buffers were changed (updated or deleted) and you don´t need to apply a Refresh. But I do not recomend it, it works like expected but it will slow down a lot your application. Eduardo |
Tue, Feb 27 2007 11:15 PM | Permanent Link |
Sam Davis | Jose Eduardo Helminsky wrote:
> Sam > > It is a matter of buffers thing. > > Your application instantiate one TDBISamTable. The DBSys instantiate other (of course) and when you delete the > records, the instance created inside your application doesn´t know if they were deleted. You need to apply a > Refresh method inside your application just before you want to rerun the tests. My application instantiated the TDBISAMTable *after* the rows were deleted. So I would have assumed it did a Refresh when the table was opened which meant it should have the buffers without the deleted rows. > > Another thing you can do is set StrictChangeDetection to True and DBISAM always check if the buffers were > changed (updated or deleted) and you don´t need to apply a Refresh. But I do not recomend it, it works like > expected but it will slow down a lot your application. But isn't that how multiuser databases are suppose to work? If someone deletes rows from a table, shouldn't the other applications be aware of it? Otherwise they are dealing with buffers that have records that no longer exist and isn't that going to create a whole mess of problems that the developer has to program around because he has to handle phantom records? I don't recall any other 3rd party database doing this, or am I mistaken? TIA Sam |
Wed, Feb 28 2007 3:27 AM | Permanent Link |
Roy Lambert NLH Associates Team Elevate | Sam
>My application instantiated the TDBISAMTable *after* the rows were >deleted. So I would have assumed it did a Refresh when the table was >opened which meant it should have the buffers without the deleted rows. If by instantiated you mean you destroyed the table and then created a new instance then yes it should have been refreshed. If your app really had closed the table and then re-opened it it should have been refreshed. Check wether it was ever closed in the first place. > >> >> Another thing you can do is set StrictChangeDetection to True and DBISAM always check if the buffers were >> changed (updated or deleted) and you don´t need to apply a Refresh. But I do not recomend it, it works like >> expected but it will slow down a lot your application. > >But isn't that how multiuser databases are suppose to work? If someone >deletes rows from a table, shouldn't the other applications be aware of >it? Otherwise they are dealing with buffers that have records that no >longer exist and isn't that going to create a whole mess of problems >that the developer has to program around because he has to handle >phantom records? I don't recall any other 3rd party database doing this, >or am I mistaken? Yes and no. The only way to do it fully is to check for changes before each and every action on the database. There's a lot of overhead associated with this. Its easier in c/s setups than local fileserver since the engine can set flags for operations (or however its done) in a fileserver environment its much more difficult. Then you get to big metal stuff and sql where you might be working with canned datasets which know nothing about the database. Roy Lambert |
Wed, Feb 28 2007 8:18 AM | Permanent Link |
"Robert" | "Sam Davis" <sammyd432@yahoo.com> wrote in message news:D6B0BF4A-41E1-4C11-AEC6-352A6A650A40@news.elevatesoft.com... > > So why doesn't TDBISAMTable know that the rows in the table have been > deleted? What am I doing wrong? I currently have StrictChangeDetection set > to False (default). > It is possible that you have the table open in your application. DBISAM acts differently on "multi user" if the table is opened twice in the same program, or if it is open by separate programs (whether that should be the case, I don't know). See project multi.zip in binaries. If you change a row in one grid and then try to change it in the other, you immediately get an 8708, even though the lock protocol is set to optimistic. However, if you load two copies of the program, you can go ahead and edit the record, and you'll only get the 8708 when you try to post (as expected). I think it has something to do with DBISAM only opening the dataset once, maybe Tim can give us some more details. Anyway, you need to be careful when opening a table multiple times in the same program, you don't get a fresh copy of the disk table. Do the following test on the multi project: 1. Start a copy of the program. Close the lower table (press the button) 2. Start another copy of the program. Change one of the rows. 3. Go back to the first program, open the second table (press button again), and you'll see that it still displays the old values. Robert |
Wed, Feb 28 2007 9:05 AM | Permanent Link |
Tim Young [Elevate Software] Elevate Software, Inc. timyoung@elevatesoft.com | Sam,
<< My application instantiated the TDBISAMTable *after* the rows were deleted. So I would have assumed it did a Refresh when the table was opened which meant it should have the buffers without the deleted rows. >> DBISAM won't do an automatic refresh when you open a table if the table is already opened elsewhere in the application. It does this for purposes of performance and maintaining coherency in what data is available to all of the table cursors in the application. -- Tim Young Elevate Software www.elevatesoft.com |
Wed, Feb 28 2007 10:54 AM | Permanent Link |
Sam Davis | Tim Young [Elevate Software] wrote:
> Sam, > > << My application instantiated the TDBISAMTable *after* the rows were > deleted. So I would have assumed it did a Refresh when the table was opened > which meant it should have the buffers without the deleted rows. >> > > DBISAM won't do an automatic refresh when you open a table if the table is > already opened elsewhere in the application. It does this for purposes of > performance and maintaining coherency in what data is available to all of > the table cursors in the application. > Yes, there was another copy of the table already opened when the second table was instantiated. So I guess they share the same buffers. I had incorrectly assumed when the table was opened it would fetch the rows from disk, not from the internal buffer. So if there are a lot of updates going on between users (POS for example), the tables in each application won't see the other's changes unless the table is refreshed. So if the program is running for a day, hundreds of changes could have been done to the table by the other user like decrementing inventory, updating invoices, etc. that the other user won't see until the table is refreshed. So what happens if user#1 opens a table at 9:00AM and user#2 at 9:10AM changes record#2. User#1 edits record#2 at 4:00PM (program has been running all day). 1) Is user#1 allowed to edit record#2, 2) or will he get an error saying it was modified by someone else? 3) of if he can edit record#2, will the values be current? From what you've told me, I suspect the answer is 2. In which case most of the records may have been changed by someone else over the course of the day. Same thing with inventory. If user#2 is filling orders and decrementing inventory, then user#1 won't see these changes unless StrictChangeDetection is set to True. Correct? If so, then I don't see any way of having StrictChangeDetection set to False in a multi-user environment where updates are occurring. Is that correct? TIA Sam |
Wed, Feb 28 2007 11:20 AM | Permanent Link |
Roy Lambert NLH Associates Team Elevate | Sam
>1) Is user#1 allowed to edit record#2, >2) or will he get an error saying it was modified by someone else? >3) of if he can edit record#2, will the values be current? > > From what you've told me, I suspect the answer is 2. Correct >In which case most >of the records may have been changed by someone else over the course of >the day. Nah that'll happen regardless >Same thing with inventory. If user#2 is filling orders and decrementing >inventory, then user#1 won't see these changes unless >StrictChangeDetection is set to True. Correct? If so, then I don't see >any way of having StrictChangeDetection set to False in a multi-user >environment where updates are occurring. Is that correct? If you want to have a grid sitting on the screen and have it constantly change as users at other stations make changes nothing will help apart from a periodic refresh. If you want to allow users to edit after the data has been changed all you need is an 8708 eater. There's a good one in the manual. If you don't like it post again and I'll send you mine. Roy Lambert |
Wed, Feb 28 2007 11:27 AM | Permanent Link |
Tim Young [Elevate Software] Elevate Software, Inc. timyoung@elevatesoft.com | Sam,
<<1) Is user#1 allowed to edit record#2, 2) or will he get an error saying it was modified by someone else? 3) of if he can edit record#2, will the values be current? From what you've told me, I suspect the answer is 2. >> Correct. << Same thing with inventory. If user#2 is filling orders and decrementing inventory, then user#1 won't see these changes unless StrictChangeDetection is set to True. Correct? If so, then I don't see any way of having StrictChangeDetection set to False in a multi-user environment where updates are occurring. Is that correct? >> Updates always use the most current version of any given row: http://www.elevatesoft.com/dbisam4d5_change_detection.htm -- Tim Young Elevate Software www.elevatesoft.com |
Wed, Feb 28 2007 11:39 AM | Permanent Link |
"Robert" | "Sam Davis" <sammyd432@yahoo.com> wrote in message news:0B0744B8-321E-4662-A763-DB7056A420FC@news.elevatesoft.com... > > So if there are a lot of updates going on between users (POS for example), > the tables in each application won't see the other's changes unless the > table is refreshed. Correct. Keep in mind that a table is also refreshed when you scroll thru a dbgrid. So if the program is running for a day, > hundreds of changes could have been done to the table by the other user > like decrementing inventory, updating invoices, etc. that the other user > won't see until the table is refreshed. So what happens if user#1 opens a > table at 9:00AM and user#2 at 9:10AM changes record#2. User#1 edits > record#2 at 4:00PM (program has been running all day). > > 1) Is user#1 allowed to edit record#2, > 2) or will he get an error saying it was modified by someone else? > 3) of if he can edit record#2, will the values be current? > Depends on the lock option. Pessimistic, you will get the 8708 as soon as you edit the record. Optimistic, you get the error when you attempt to post. In either case, the values are not current until you refresh the record. > From what you've told me, I suspect the answer is 2. In which case most of > the records may have been changed by someone else over the course of the > day. > > Same thing with inventory. If user#2 is filling orders and decrementing > inventory, then user#1 won't see these changes unless > StrictChangeDetection is set to True. Correct? If so, then I don't see any > way of having StrictChangeDetection set to False in a multi-user > environment where updates are occurring. Is that correct? > StrictChangeDetection is a very poor solution, IMO. But then again, it all depends on the application. Read the change detection section in the DBISAM manual, it is very good as is all the rest of the concurrency documentation. Also keep in mind that if you want to do an update to a row without consideration of previous values (for example, when increasing or decreasing inventory), you can use SQL. That way, you don't have to worry about an 8708. Robert |
Page 1 of 2 | Next Page » | |
Jump to Page: 1 2 |
This web page was last updated on Sunday, May 19, 2024 at 08:46 AM | Privacy PolicySite Map © 2024 Elevate Software, Inc. All Rights Reserved Questions or comments ? E-mail us at info@elevatesoft.com |