lidagon
lidagon

Reputation: 45

Deadlock management

I am doing a research but any relevant information is hard to find. I stumbled upon this problem:

Produce a wait-for-graph for the following transaction scenario and determine whether deadlock exists.

Transaction:

T1
T2
T3
T4
T5
T6
T7
T8
T9
T10 

Data items locked by transaction:

X1,X2,X3
X4,X5,X6
X7,X8
X9,X10
X11,X12
X13,X14
X15
X1111 
X115
X199

Data items transaction is waiting for:

X4,X5,X6,X7
X7,X8,X9
X1,X10,X111
X7,X11,X12
X5
X6,X1,X2,X3,X11,X12
X5
X1,X115
X1
X11,X12

Now, as far as I've seen on transaction management, this striked me as quite hard. Can someone provide reference to explanation how to solve this type of problem, or help anyhow?

Upvotes: 1

Views: 892

Answers (1)

ninjalj
ninjalj

Reputation: 43688

As is quite common, the key to resolving some problems is choosing a good representation. If you represent your problem in tabular form:

T1 =>  { locked => [ qw( X1 X2 X3 ) ], waiting => [ qw( X4 X5 X6 X7         ) ] },
T2 =>  { locked => [ qw( X4 X5 X6 ) ], waiting => [ qw( X7 X8 X9            ) ] },
T3 =>  { locked => [ qw( X7 X8    ) ], waiting => [ qw( X1 X10 X111         ) ] },
T4 =>  { locked => [ qw( X9 X10   ) ], waiting => [ qw( X7 X11 X12          ) ] },
T5 =>  { locked => [ qw( X11 X12  ) ], waiting => [ qw( X5                  ) ] },
T6 =>  { locked => [ qw( X13 X14  ) ], waiting => [ qw( X6 X1 X2 X3 X11 X12 ) ] },
T7 =>  { locked => [ qw( X15      ) ], waiting => [ qw( X5                  ) ] },
T8 =>  { locked => [ qw( X1111    ) ], waiting => [ qw( X1 X115             ) ] },
T9 =>  { locked => [ qw( X115     ) ], waiting => [ qw( X1                  ) ] },
T10 => { locked => [ qw( X199     ) ], waiting => [ qw( X11 X12             ) ] },

then you can reason more effectively about the problem at hand. It's easy to see what resources a certain transaction is waiting for, and from there you can see which transactions holds those resources. Apply that reasoning recursively. If you end up in a cycle, you've just found a deadlock.

'Course, the representation can even be better:

use strict;
use warnings;

use Data::Dumper;

my %transactions = (
    T1 =>  { locked => [ qw( X1 X2 X3 ) ], waiting => [ qw( X4 X5 X6 X7         ) ] },
    T2 =>  { locked => [ qw( X4 X5 X6 ) ], waiting => [ qw( X7 X8 X9            ) ] },
    T3 =>  { locked => [ qw( X7 X8    ) ], waiting => [ qw( X1 X10 X111         ) ] },
    T4 =>  { locked => [ qw( X9 X10   ) ], waiting => [ qw( X7 X11 X12          ) ] },
    T5 =>  { locked => [ qw( X11 X12  ) ], waiting => [ qw( X5                  ) ] },
    T6 =>  { locked => [ qw( X13 X14  ) ], waiting => [ qw( X6 X1 X2 X3 X11 X12 ) ] },
    T7 =>  { locked => [ qw( X15      ) ], waiting => [ qw( X5                  ) ] },
    T8 =>  { locked => [ qw( X1111    ) ], waiting => [ qw( X1 X115             ) ] },
    T9 =>  { locked => [ qw( X115     ) ], waiting => [ qw( X1                  ) ] },
    T10 => { locked => [ qw( X199     ) ], waiting => [ qw( X11 X12             ) ] },
);

# get a data-item -> transaction mapping
my %items;
for my $transaction (keys %transactions) {
    for my $item (@{$transactions{$transaction}->{locked}}) {
            $items{$item} = $transaction;
    }
}

my @nodes;
my @edges;
for my $transaction (keys %transactions) {
    push @nodes, $transaction;
    for my $item (@{$transactions{$transaction}->{waiting}}) {
            push @edges, { source => $transaction, dest => $items{$item}, item => $item } if $items{$item};
    }
}

print "digraph tx_dependencies {\n";
print "    $_ label=$_;\n" for @nodes;
print "    @{[ $_->{source} ]} -> @{[ $_->{dest} ]} [label=@{[ $_->{item} ]}];\n" for @edges;
print "}\n";

This program spews a graphviz file, which when massaged appropriately with dot ends up as:

digraph tx_dependencies {T1 label=T1;T9 label=T9;T8 label=T8;T3 label=T3;T4 label=T4;T6 label=T6;T7 label=T7;T5 label=T5;T10 label=T10;T2 label=T2;T1 -> T2 [label=X4];T1 -> T2 [label=X5];T1 -> T2 [label=X6];T1 -> T3 [label=X7];T9 -> T1 [label=X1];T8 -> T1 [label=X1];T8 -> T9 [label=X115];T3 -> T1 [label=X1];T3 -> T4 [label=X10];T4 -> T3 [label=X7];T4 -> T5 [label=X11];T4 -> T5 [label=X12];T6 -> T2 [label=X6];T6 -> T1 [label=X1];T6 -> T1 [label=X2];T6 -> T1 [label=X3];T6 -> T5 [label=X11];T6 -> T5 [label=X12];T7 -> T2 [label=X5];T5 -> T2 [label=X5];T10 -> T5 [label=X11];T10 -> T5 [label=X12];T2 -> T3 [label=X7];T2 -> T3 [label=X8];T2 -> T4 [label=X9];}

Upvotes: 2

Related Questions