The general method for making a "transaction" is like this:
- Preserve the old data in place
- Write the new data to a temporary area
- Perform an atomic operation to replace the old data with the new, e.g. by updating a pointer.
For in-memory operations, this is achieved trivially by using an object reference to point to state:
class Program
{
static Point _position; //Points to latest position of something
static void Move(int x, int y)
{
var temp = new Point(x, y);
_position = temp;
}
}
This example allows the program to move an object while guaranteeing that x
and y
are updated together.
For non-memory operations, the implementation of this pattern is specific to the medium. For example, for file operations, the program might write to a temporary file. When all operations are complete, the program would rename the file to the path expected by the user. This is probably how your browser's download feature works.
A similar mechanism exists for graphics (a frame buffer) and audio (audio buffer). And of course databases have their own particular mechanism that supports atomicity and concurrency, among other things.