Level Extreme platform
Subscription
Corporate profile
Products & Services
Support
Legal
Français
Buffering vs Begin..End Transaction
Message
General information
Forum:
Visual FoxPro
Category:
Other
Miscellaneous
Thread ID:
00305569
Message ID:
00305746
Views:
28
Excuse me, I slightly mis-spoke here... you can in fact have Tx's with unbuffered tables. I got caught up in the fact that I thought a view was involved, and we all know that you cannot have an unbuffered view.

Still though, it is not an either or thing....

>And so ends the lesson...
>
>Seriously Jim... This thread pretty much encapsulates the issues I have with a lot of responses around here.. For the first response to NOT issue the fact that you cannot have Tx's without buffering, and that transactions are complimentary to buffering is pretty sad...<s>....
>
>I'm sorry I did'nt see this thread sooner.....
>
>
>>Jess and others,
>>
>>There is nothing complicated about a transaction in combination with buffering, as a matter of fact, you CANNOT have a transaction unless the tables are buffered and in a DBC.
>>
>>The most common reason someone has a problem with a transaction is that they think it does more than it does, or they are trying to get it to do more (like do data buffering).
>>
>>Ok buffering first:
>>
>>In FP 2.x we would scatter memver and then let users edit the memvars, why? Because we wanted to be able to discard the user's work if they chose to do that by not Gathering the data back into the table. The other reason was that FP 2.x would write the changes directly to disk if we connected the GETs to the fields directly, right? Wrong! If that were true then the disk drive light would flash with every keystroke and it didn't. Fox 2.x was buffering the edited data in memory to be written at some future time. However, we had no control over when and if that buffered data was going to be written. Data buffering in VFP gives us that control. We can now allow direct editing of fields and then use either TableUpdate or TableRevert to write or discard the changes made respectively. That is the purpose of data buffering.
>>
>>Now for transactions:
>>
>>A transaction is used to group a series of data updates into a single all or none operation. A good example is saving an invoice. The user has completed the data entry and has clicked the save button. We now must issue tableupdates on the customer table to post the new balance, the invoice table to add the invoice header record, the invoice details table to save teh detail lines, the inventory table to reduce the on-hand levels of what was sold, adn the accounts receivable table to set up the AR record.
>>
>>What happens if we get the customer, invoice and half of the details saved and the system crashes? We get a database that is corrupt and not recoverable. Why not recoverable, because the invoice is neither in the data nor not in the data, it is partially in the data. The recovery would much cleaner if the invoice was clearly either there or not there. This is the purpose of a transaction.
>>
>>Both the nature of a transaction and the process that VFP uses to implement transactions require that we keep teh duration of the transaction to the shortest possible time period. That means all calculations should be completed before the BEGIN TRANSACTION is issued. Inside the transaction should very little more than a series of tableupdates(). IN the Invoice example, the save code might look something like this;
>>
>>
>>* Save Invoice
>>REPLACE Customer.Balance WITH Customer.Balance + Invoice.TotalAmount IN Customer
>>* Other claculations that are needed here
>>
>>
>>* Ok the calcs are done so we are ready for the transaction
>>LOCAL llRollBack
>>llRollBack = .F.
>>
>>BEGIN TRANSACTION
>>
>>IF NOT TableUpdate(1,.F.,"Customer")
>>   llRollBack = .T.
>>ENDIF
>>
>>IF NOT llRollBack AND NOT TableUpdate(1,.F.,"Customer")
>>   llRollBack = .T.
>>ENDIF
>>
>>IF NOT llRollBack AND NOT TableUpdate(1,.F.,"Invoice")
>>   llRollBack = .T.
>>ENDIF
>>
>>IF NOT llRollBack AND NOT TableUpdate(1,.F.,"InvDetails")
>>   llRollBack = .T.
>>ENDIF
>>
>>IF NOT llRollBack AND NOT TableUpdate(1,.F.,"Inventory")
>>   llRollBack = .T.
>>ENDIF
>>
>>IF NOT llRollBack AND NOT TableUpdate(1,.F.,"AcctRcvbl")
>>   llRollBack = .T.
>>ENDIF
>>
>>IF llRollBack
>>   ROLLBACK
>>ELSE
>>   END TRANSACTION
>>ENDIF
>>
>>
>>This code will attempt to update each of the tables, if they all succeed it will issue the end trans and the data will be committed. If any one of the updates fails, then the rollback will be issued and everything will be reversed with nothing having been saved.
>>
>>Now if you issue the rollback, keep in mind that the data buffers are stiill "dirty", that is they have all of the pending changes in them. To clean the buffers you need to tablerevert each of them.
>>
>>Why don't I tableRevert right after the rollback in the above code? Because the reason for failure may be a conflict with another user that is temporary and the user could simple click teh Save button and try again to save their work. Essentially, I don't believe in discarding the user's work unless they explicitly tell me that's what they want.
Previous
Reply
Map
View

Click here to load this message in the networking platform