roPopa 0 Posted January 23, 2022 I have the following logical problem developing an app. I need to do several key operations that need to be executed only once. Lets say I need to print something on a fiscal printer. I have several records stored on the database. I send one command to the printer and the result is ok (was printed successfully). I save on that specific line the fact that was printed ok, so if the program is somehow stopped, on resume that line is already printed and will be skipped from sent to printer. However if I cannot write in the database the answer (the program crash) on resume the line will be printed again. This operation is obvious not an atomic operation. So I need one protocol to ensure this functionality. Is there any? Many thanks Share this post Link to post
FPiette 383 Posted January 23, 2022 You could use a database transaction. Begin the transaction before printing and commit the transaction after printing. Roll the transaction back if printing failed. If a program crash occurs while printing or before the program crashes, the transaction will automatically rolled back. 1 Share this post Link to post
PeterBelow 238 Posted January 23, 2022 (edited) 1 hour ago, roPopa said: I have the following logical problem developing an app. I need to do several key operations that need to be executed only once. Lets say I need to print something on a fiscal printer. I have several records stored on the database. I send one command to the printer and the result is ok (was printed successfully). I save on that specific line the fact that was printed ok, so if the program is somehow stopped, on resume that line is already printed and will be skipped from sent to printer. However if I cannot write in the database the answer (the program crash) on resume the line will be printed again. This operation is obvious not an atomic operation. So I need one protocol to ensure this functionality. Is there any? Many thanks A kind of transaction log saved to local storage (a file) may serve your purpose. You can write entries to a file using a write followed by a flush operation (or a full open - write - close cycle) . While not very fast it will ensure the entry is either written completely or not all (if the PC suffers a power failure, for example). Your operation would then follow this scheme: Write the intent to print, with the ID of the item to print, to the log print the item write the success of the operation to the log save it to the database write an end of transactio to the log or delete the log On (re)start the program can then look for a transaction log and analyse it to see how far it got on the last run. Edited January 23, 2022 by PeterBelow Share this post Link to post
Vandrovnik 214 Posted January 23, 2022 (edited) In my opinion, in these situation you sometimes have to ask the user. Even when data is sent to printer, it does not mean it was really printed OK (out of paper, damaged printout...). Edited January 23, 2022 by Vandrovnik Share this post Link to post
Fr0sT.Brutal 900 Posted January 24, 2022 I'm afraid there's no 100% reliable solution. There always could be points where atomicity could be broken (print succeeded - app crashed - oops) Share this post Link to post
Steven Kamradt 20 Posted March 2, 2022 Maybe a state variable and a work queue? You would add to the work queue the item that needs to be processed and its current state. Somewhere in your application (maybe a separate thread or on idle) loop through the queue and investigate each state to see if its eligible to move to the next state or be removed from the queue. If you persist this queue (database or file) you can then on program crash and reload determine if there is a state which would need to be restarted or not. Share this post Link to post
Clément 148 Posted March 4, 2022 For a good solution you must work both ends. The application, the device and the connection between them can crash, this is why is very important to be able to query the device! From your application: 1. Write down some identification ( file, table record, etc) 2. Send the data 3. Store the answer ( delete the file, update record status etc) From the fiscal printer, in case of a crash you need to query the ID you sent: a. If file exists or record is in open state then read the ID and query the device for that ID status b. If data was not sent, the device will return with an error, in this case pick up from step 2 c. if data was sent, the device should answer properly, in this case start from step 3 If you can't query the device, you will get a half baked solution to your problem. Share this post Link to post