Beefy Boxes and Bandwidth Generously Provided by pair Networks
Think about Loose Coupling
 
PerlMonks  

DBM::Deep: Cannot allocate transaction ID

by fanasy (Sexton)
on Jan 10, 2021 at 02:46 UTC ( [id://11126687]=perlquestion: print w/replies, xml ) Need Help??

fanasy has asked for the wisdom of the Perl Monks concerning the following question:

Hi Monks,
I have the read/write one DBM database by about 10-20 scripts. the read/write hang on long time . so I kill the process of read/write process by "kill" linux command.
However,I try to re-read/write the same DBM database with same script.
the error out:
DBM::Deep: Cannot allocate transaction ID at
how to solve this ? or my DBM database broken ?

sub writeToDB { say "start to writeToDB"; my $dbName = shift || "LMT.db"; my $pName = shift; my $date= shift; my $hashRef= shift; my $db = DBM::Deep->new( file=> $dbName, num_txns=> 10, ); eval { $db->begin_work; foreach ( keys %$hashRef) { push @{$db->{$pName}->{$date}->{$_}},$hashRef->{$_}; } $db->commit; }; if(defined $@ and length $@) { say $@; $db->rollback; } }

Replies are listed 'Best First'.
Re: DBM::Deep: Cannot allocate transaction ID
by kcott (Archbishop) on Jan 10, 2021 at 03:41 UTC

    G'day fanasy,

    [Disclaimer: I'm not a user of DBM::Deep. The following are just suggestions.]

    Instead of kill, which sends a kill -KILL signal, try gentler methods of termination. Some suggestions: kill -QUIT; kill -HUP; kill -TERM.

    $@ could be modified before the code gets to the if block. Try writing your eval like this:

    eval { ... $db->commit; 1; } or do { say $@ if length $@; $db->rollback; };

    [Note: If you have Perl 5.12 or later, "length (v5.12.0)" handles the defined for you.]

    Check through the DBM::Deep for possible solutions. You didn't give much information in your OP. If, for instance, you're using large files, the "LARGEFILE SUPPORT" section may prove useful. Check other sections, as appropriate.

    Check "Active bugs for DBM-Deep" for problems similar to yours: there may be solutions or workarounds. "Bug #130395 for DBM-Deep: Fail gracefully when database hits max size" looked like it might be similar to your problem; although, that's just a report with no fix, solution or workaround.

    I do note that active bugs have been posted over 13 years but not a single one has an entry in the "Fixed in" column. Also, this module has not been updated in almost three years; I wouldn't hold your breath for fixes to any of them.

    — Ken

      G'day Ken,
      thanks for your quick help.
      I checked the source code of File.pm in DBM/Deep/Engine/.
      the error caused by transaction slots full
      the question become how to reset transaction slots ? I am keeping to debug.

      sub begin_work { use Data::Dumper; my $self = shift; my ($obj) = @_; unless ($self->supports('transactions')) { DBM::Deep->_throw_error( "Cannot begin_work unless transaction +s are supported" ); } if ( $self->trans_id ) { DBM::Deep->_throw_error( "Cannot begin_work within an active t +ransaction" ); } my @slots = $self->read_txn_slots; print Dumper(@slots); my $found; for my $i ( 0 .. $self->num_txns-2 ) { print "i,$i\n"; next if $slots[$i]; $slots[$i] = 1; $self->set_trans_id( $i + 1 ); $found = 1; last; } unless ( $found ) { DBM::Deep->_throw_error( "Cannot allocate transaction ID" ); } $self->write_txn_slots( @slots ); if ( !$self->trans_id ) { DBM::Deep->_throw_error( "Cannot begin_work - no available tra +nsactions" ); } no Data::Dumper; return; }
        sub begin_work { use Data::Dumper; ... lotsa code no Data::Dumper; return; }

        This doesn't address your immediate problem, but application code modules like Data::Dumper do not follow the lexical scoping rules that pragma modules like strict, warnings and integer follow.

        The effects of the use Data::Dumper; statement are seen from the point in the file at which the module is use-ed at compile time and in all code beyond that point.

        Win8 Strawberry 5.8.9.5 (32) Sun 01/10/2021 10:52:26 C:\@Work\Perl\monks >perl -Mstrict -Mwarnings # pm#11126693 foo(); # try disabling this statement print Dumper [ qw(1 2 3) ]; # print() on unopened filehandle Dumper # foo(); # try enabling this statement sub foo { use Data::Dumper; print Dumper [ qw(a b c) ]; no Data::Dumper; # has no effect print Dumper [ qw(x y z) ]; } print Dumper [ qw(9 8 7) ]; # prints as expected ^Z $VAR1 = [ 'a', 'b', 'c' ]; $VAR1 = [ 'x', 'y', 'z' ]; print() on unopened filehandle Dumper at - line 5. $VAR1 = [ '9', '8', '7' ];
        Same results running under Perl version 5.30.3.1.

        Update: Another little twist to consider is the effect of adding a declaration of the Dumper subroutine in the main package before the first call to Dumper (and before the use Data::Dumper; statement):

        sub Dumper; print Dumper [ qw(1 2 3) ]; # print() on unopened filehandle Dumper
        What happens and why? Is there another way to identify Dumper to the compiler as a subroutine? What would happen if one wrote:
        ### sub Dumper; print Dumper([ qw(1 2 3) ]); # print() on unopened filehandle Dumper
        (I see the same results under both versions 5.8.9 and 5.30.3.)


        Give a man a fish:  <%-{-{-{-<

Re: DBM::Deep: Cannot allocate transaction ID
by fanasy (Sexton) on Jan 11, 2021 at 08:27 UTC

    I solved my issue:
    DBM database deadlock on transaction slots by workaround
    I use below code once in my exist database, than I comment below code.
    $self->write_txn_slots( @slots )
    in DBM/Deep/Engine/File.pm's begin_work sub
    @slots array of 0.
    now transation slots are all 0 .

A reply falls below the community's threshold of quality. You may see it by logging in.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://11126687]
Approved by kcott
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others exploiting the Monastery: (5)
As of 2024-04-26 09:13 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found