I have been getting some issues with using BerkeleyDB. I've multiple instances of the identical code pointed to some single repository of DB files, and everything runs acceptable for 5-32 hrs, then all of a sudden there's a deadlock. The command prompts stop before performing a db_get or db_put or cursor creation call. So I am simply requesting the best way to handle these calls. Here's my general layout:

This is the way the atmosphere and DBs are produced:

my $env = new BerkeleyDB::Env ( 
   -Home   => "$dbFolder\\" , 
   -Flags  => DB_CREATE | DB_INIT_CDB | DB_INIT_MPOOL) 
   or die "cannot open environment: $BerkeleyDB::Error\n";

my $unsortedHash  = BerkeleyDB::Hash->new (
   -Filename => "$dbFolder/Unsorted.db", 
   -Flags => DB_CREATE,
   -Env  => $env
   ) or die "couldn't create: $!, $BerkeleyDB::Error.\n";

Just one demonstration of this code runs, would go to a website and saves Web addresses to become parsed by another instance (I've the flag set to ensure that every DB is locked when the first is locked):

        $lk = $unsortedHash->cds_lock();
        while(@urlsToAdd){
            my $currUrl = shift @urlsToAdd;
            $unsortedHash->db_put($currUrl, '0');
        }
        $lk->cds_unlock();

It periodically inspections if your certain quantity of products have been in Unsorted:

$refer = $unsortedHash->db_stat();
$elements = $refer->{'hash_ndata'};

Before adding any element to the DB, it first inspections all DBs to ascertain if that element has already been present:

if ($unsortedHash->db_get($search, $value) == 0){
    $value = "1:$value";
}elsif ($badHash->db_get($search, $value) == 0){
    $value =  "2:$value";
....

This next code uses, and several cases of it are run in parallel. First, it will get the following item in unsorted (without peak value '1'), then sets the worthiness to busy '1', then does something by using it, then moves the DB entry completely to a different DB (it's taken off unsorted and saved in another DB):

my $pageUrl = '';
my $busy = '1';
my $curs;
my $lk = $unsortedHash->cds_lock(); #lock, change status to 1, unlock
########## GET AN ELEMENT FROM THE UNSORTED HASH #######
while(1){
    $busy = '1';
    $curs = $unsortedHash->db_cursor();
    while ($busy){
        $curs->c_get($pageUrl, $busy, DB_NEXT);
        print "$pageUrl:$busy:\n";
        if ($pageUrl eq ''){
            $busy = 0;
        }
    }
    $curs->c_close();
    $curs = undef;

    if ($pageUrl eq ''){
        print "Database empty. Sleeping...\n";
        $lk->cds_unlock();
        sleep(30);
        $lk = $unsortedHash->cds_lock();
    }else{
        last;
    }
}

####### MAKE THE ELEMENT 'BUSY' AND DOWNLOAD IT 


$unsortedHash->db_put($pageUrl, '1');
$lk->cds_unlock();
$lk = undef;

As well as in almost every other place, basically call db_put or db_del on ANY DB, it's wrapped having a lock like so:

print "\n\nBad.\n\n";
        $lk = $badHash->cds_lock();
        $badHash->db_put($pageUrl, '0');
        $unsortedHash->db_del($pageUrl);
        $lk->cds_unlock();
        $lk = undef;

However, my db_get instructions have the freedom-floating without any lock, because I do not think reading through requires a lock.

I've viewed this code millions of occasions and also the formula is airtight. And So I am just wondering should i be applying any thing about this wrong, while using locks wrong, etc. Or maybe there's an easy method to avoid deadlocking (as well as identify deadlocking) with BerkeleyDB and Strawberry Perl?

UPDATE: To become more specific, the issue is occurring on the Home windows 2003 server (1.5 GB RAM, unsure if that's important). I'm able to run this complete setup fine on my small Home windows 7 machine (4GB RAM). I additionally began making the lock stats while using following:

Adding this flag towards the atmosphere creation:

-MsgFile => "$dbFolder/lockData.txt"

After which calling this every a minute:

my $status = $env->lock_stat_print();
print "Status:$status:\n";

The status is definitely came back as , that is success. This is actually the last stat report:

29  Last allocated locker ID
0x7fffffff  Current maximum unused locker ID
5   Number of lock modes
1000    Maximum number of locks possible
1000    Maximum number of lockers possible
1000    Maximum number of lock objects possible
40  Number of lock object partitions
24  Number of current locks
42  Maximum number of locks at any one time
5   Maximum number of locks in any one bucket
0   Maximum number of locks stolen by for an empty partition
0   Maximum number of locks stolen for any one partition
29  Number of current lockers
29  Maximum number of lockers at any one time
6   Number of current lock objects
13  Maximum number of lock objects at any one time
1   Maximum number of lock objects in any one bucket
0   Maximum number of objects stolen by for an empty partition
0   Maximum number of objects stolen for any one partition
3121958 Total number of locks requested
3121926 Total number of locks released
0   Total number of locks upgraded
24  Total number of locks downgraded
9310    Lock requests not available due to conflicts, for which we waited
0   Lock requests not available due to conflicts, for which we did not wait
8   Number of deadlocks
1000000 Lock timeout value
0   Number of locks that have timed out
1000000 Transaction timeout value
0   Number of transactions that have timed out
792KB   The size of the lock region
59  The number of partition locks that required waiting (0%)
46  The maximum number of times any partition lock was waited for (0%)
0   The number of object queue operations that required waiting (0%)
27  The number of locker allocations that required waiting (0%)
0   The number of region locks that required waiting (0%)
1   Maximum hash bucket length

Which I'm cautious about this:

8   Number of deadlocks

How did these deadlocks occur, and just how were they resolved? (every part from the code continue to be running). What is a deadlock, within this situation?