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ようになります。

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];}

于 2012-09-26T22:22:42.037 に答える