Locksim

Locksim is a simulator for database locking, to try out various locking methods such as two-phase locking. It supports multiple transactions and both binary and read/write locks.

Downloads

Locksim has been tested on Linux (Ubuntu 14.04) and on Windows (Windows 7 and Windows 10 Technical Preview).

Download source code: locksim-0.3-source.tar.gz for Linux, locksim-0.3-source.zip for Windows

New! There is also a project for Visual Studio 2013, which might be easier to get started with for Windows Users: Locksim-0.3-project.zip Read more in the Windows instructions.

Newer! Since not everyone had Visual Studio 2013 installed, here is also a project for Visual Studio 2012: Locksim-0.3-VS2012.zip

Usage

A scenario with database data and specification of the transactions is written in a text file. Then locksim is started using the command line:
locksim  [ -v VERBOSITY ]  [ -s SEED ]  [ -r REPS ] SCENARIO-FILE
SCENARIO-FILE is the name of the scenario file. The optional REPS is the number of times to run the scenario. The default is 1. The optional SEED is the seed used for the pseudo-random number generator. The default is a seed based on the current time.

The optional VERBOSITY is the verbosity level, i. e. how much the program should print. The default is 1, and prints the results after each execution of the scenario, plus a summary at the end. Verbosity level 0 only prints the summary at the end. Higher verbosity levels (2 and 3) will add more printouts about what happens.

An example scenario

Lotta and Kalle are friends. They have some money in their bank accounts, and both of them want to give away their money to the other person. Here is a scenario file called swap.txt:
Lotta = 100;
Kalle = 50;

transaction Lotta {
    Read(Lotta);
    Gift = Lotta;
    Lotta = 0;
    Write(Lotta);
    Read(Kalle);
    Kalle = Kalle + Gift;
    Write(Kalle);
}

transaction Kalle {
    Read(Kalle);
    Gift = Kalle;
    Kalle = 0;
    Write(Kalle);
    Read(Lotta);
    Lotta = Lotta + Gift;
    Write(Lotta);
}
The database contains two data objects, the variables Lotta and Kalle, which are the balances of two bank accounts belonging to Lotta and Kalle. In transaction T1 Lotta gives away her money to Kalle. In transaction T2 Kalle gives away his money to Lotta.

Some explanations of the commands in the file:

If the transactions are run serially, or in a serializable schedule, one person ends up with all the money, and the other none. Either Kalle will first give all his money to Lotta, and Lotta will then give all the money to Kalle, so Kalle ends up with all the money and Lotta none, or Lotta will first give all her money to Kalle, and Kalle will then give all the money to Lotta, so Lotta ends up with all the money and Kalle none,

We run the scenario one million times with this command:

locksim -r 1000000 -v 0 swap.txt 
Since the two transactions concurrently modify the variables without locking, we can get some unexpected results. Here is the output from Locksim:
Tried the scenario in 'swap.txt' 1000000 times.
There were 7 different results:
7780 times: 2 variables: Lotta = 150, Kalle = 0
7857 times: 2 variables: Lotta = 0, Kalle = 150
273523 times: 2 variables: Lotta = 50, Kalle = 100
192036 times: 2 variables: Lotta = 150, Kalle = 100
163699 times: 2 variables: Lotta = 0, Kalle = 100
191644 times: 2 variables: Lotta = 50, Kalle = 150
163461 times: 2 variables: Lotta = 50, Kalle = 0
To avoid these concurrency problems, we can add locking. Here we have used two-phase locking with read/write locks:
Lotta = 100;
Kalle = 50;

transaction Lotta {
    ReadLock(Lotta);
    Read(Lotta);
    Gift = Lotta;
    Lotta = 0;
    WriteLock(Lotta);
    Write(Lotta);
    ReadLock(Kalle);
    Read(Kalle);
    Kalle = Kalle + Gift;
    WriteLock(Kalle);
    Unlock(Lotta);
    Write(Kalle);
    Unlock(Kalle);
}

transaction Kalle {
    ReadLock(Kalle);
    Read(Kalle);
    Gift = Kalle;
    Kalle = 0;
    WriteLock(Kalle);
    Write(Kalle);
    ReadLock(Lotta);
    Read(Lotta);
    Lotta = Lotta + Gift;
    WriteLock(Lotta);
    Unlock(Kalle);
    Write(Lotta);
    Unlock(Lotta);
}

Some explanations of the locking commands:

Now the output from Locksim looks like this:

Tried the scenario in 'swap-rw-2PL.txt' 1000000 times.
There were 5 different results:
940 times: 2 variables: Lotta = 150, Kalle = 0
935 times: 2 variables: Lotta = 0, Kalle = 150
453221 times: *** Deadlock! *** 2 variables: Lotta = 0, Kalle = 0
*** Deadlock! ***
272600 times: *** Deadlock! *** 2 variables: Lotta = 0, Kalle = 50
*** Deadlock! ***
272304 times: *** Deadlock! *** 2 variables: Lotta = 100, Kalle = 0
*** Deadlock! ***
As we can see, this locking schema most often leads to deadlock, but when the scenario is finished without deadlock, we get only the two expected results.

Some notes

Author

Locksim is written by Thomas Padron-McCarthy (thomas.padron-mccarthy@oru.se).

License

Locksim is free software licensed under the GNU General Public License version 2. Share and enjoy. No warranty.


Thomas Padron-McCarthy (thomas.padron-mccarthy@oru.se), January 29, 2015