1

我正在做一项研究,但很难找到任何相关信息。我偶然发现了这个问题:

为以下事务场景生成等待图并确定是否存在死锁。

交易:

T1
T2
T3
T4
T5
T6
T7
T8
T9
T10 

事务锁定的数据项:

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

数据项事务正在等待:

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

现在,就我在事务管理方面所见,这让我非常震惊。有人可以提供参考解释如何解决此类问题,或者无论如何提供帮助吗?

4

1 回答 1

2

很常见的是,解决一些问题的关键是选择一个好的表示。如果您以表格形式表示您的问题:

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             ) ] },

然后你可以更有效地推理手头的问题。很容易看到某个事务正在等待什么资源,从那里你可以看到哪些事务持有这些资源。递归地应用该推理。如果你最终进入一个循环,你刚刚发现了一个死锁。

'当然,表示甚至可以更好:

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";

该程序会生成一个 graphviz 文件,当对其进行适当的按摩时,dot最终结果为:

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

于 2012-09-26T22:22:42.037 回答