... that if the computer turns off, let's say the data is saved after shutdown
To ensure the sustainability of “as in a DBMS”, you need to introduce the concept of a transaction into the program, store information about transactions in a permanent memory (keep a transaction log), implement the rollback / redo logic.
Solution: keep the lock in permanent memory. Next pseudocode:
//создаем запись в журнале транзакций, //которая хранится в постоянном хранилище: //в базе данных, файловой системе и т.п. Transaction transaction = bank.createTransaction(from, to); ... //выполняем операции ... //отмечаем транзакцию как завершенную transaction.finish();
For simplicity, lowered exception handling.
If the computer turns off, the next time you start the application, it will read from the log entries about incomplete transactions and process them as necessary: either roll back, finish it, or inform the user about data problems.
Also, for the correct operation of the above code, you will need to implement reliable transaction isolation . For example, after this line:
toAtomicInteger.addAndGet(sum);
another transaction may be executed, which will transfer money from the modified to account to the third account and successfully complete. If an error occurs after this, then the current transaction can no longer be rolled back painlessly. You can avoid this kind of errors by blocking accounts for the duration of the operation. Accordingly, such locks should also be stored in permanent memory.
DBMSs usually provide built-in transaction management mechanisms.