2014-05-13 95 views
1

我使用AnyEvent每X分鐘觸發事件。某些過程很長,記錄在數據庫中的結果有時很長(有時超過3秒)。我想確保只有一個函數可以同時訪問我的數據庫。所以我使用來自threads :: shared模塊的鎖。這裏是我的代碼:我可以使用來自threads :: shared模塊(如互斥鎖)的鎖嗎?

main.pl:

my $var :shared; 
$var = 0; 

my $w1 = AnyEvent->timer(after => 0, interval => 120, cb => sub { 
my @targeted_users = TargetUsers::get_targeted_account_from_followers($dbh,$account,'myrhline'); 
TargetUsers::save_users_to_follow($dbh,'RH',$var,@targeted_users); 
}); 

my $w2 = AnyEvent->timer(after => 0, interval => 120, cb => sub { 
my @targeted_users2 = TargetUsers::get_targeted_account_from_followers($dbh,$account2,'actuel_rh'); 
TargetUsers::save_users_to_follow($dbh,'RH',$var,@targeted_users2); 
}); 

AnyEvent::Loop::run; 

TargetUsers:

sub save_users_to_follow{ 
my ($dbh,$topic,$var,@targeted_users) = @_; 

lock($var); #I call lock($var) to lock the access to the database. 

my @array1 =(); 

$dbh->{AutoCommit} = 0; 

my $sth2 = $dbh->prepare(
"UPDATE People_TO_FOLLOW 
     SET Pertinence  = Pertinence + 1 
     WHERE Id_user = ?"); 

my $tuples_update = $sth2->execute_array(
{ ArrayTupleStatus => \my @tuple_status_update }, 
\@targeted_users, 
); 

if ($tuples_update) { 
print "Successfully updated $tuples_update records\n"; 
} 
else { 
for my $tuple_1 (0..$#targeted_users) { 
    my $status_1 = $tuple_status_update[$tuple_1]; 
    $status_1 = [0, "Skipped"] unless defined $status_1; 
    next unless ref $status_1; 
    printf "Failed to update (%s): %s\n", 
     $targeted_users[$tuple_1], $status_1->[1]; 
} 
} 
$sth2->finish(); 

my $sth = $dbh ->prepare(
"INSERT OR IGNORE INTO People_TO_FOLLOW(Id_user,Topic,Already_followed,Pertinence) VALUES (?,'$topic',0,1)"); 

my $tuples_insert = $sth->execute_array(
{ ArrayTupleStatus => \my @tuple_status_insert }, 
\@targeted_users, 
); 

if ($tuples_insert) { 
print "Successfully inserted $tuples_insert records\n"; 
} 
else { 
for my $tuple_2 (0..$#targeted_users) { 
    my $status_2 = $tuple_status_insert[$tuple_2]; 
    $status_2 = [0, "Skipped"] unless defined $status_2; 
    next unless ref $status_2; 
    printf "Failed to insert (%s): %s\n", 
    $targeted_users[$tuple_2], $status_2->[1]; 
} 
} 
$sth->finish(); 
$dbh->commit; 
$dbh->{AutoCommit} = 1;  
} 

但我得到這個錯誤:

擁有 「鎖只能在共同的價值觀可以用」你有一些想法嗎?由於

+0

對於什麼是值得的,大多數數據庫允許併發訪問,而無需鎖定任何東西。確實很難按照你想要的方式更新數據庫(比如說「添加10」到賬戶),所以這對你來說可能不夠好,但也有可能你解決了一個問題,需要解決。 –

回答

4

您有一個名爲$var 2個瓦爾,一個在main.pl,和一個在save_users_to_follow。前者是共享變量,但你試圖鎖定後者。

將var從main移動到TargetUsers,或將對var的引用傳遞到save_users_to_follow