Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Potential bug "Transaction Terminated", or documentation issue, for use of $txn reset/renew #20

Open
akotlar opened this issue Aug 30, 2016 · 1 comment

Comments

@akotlar
Copy link
Contributor

akotlar commented Aug 30, 2016

My use case below. "Transaction Terminated" returned when $txn->renew() called. I don't think this is the expected behavior, because transaction termination should only occur if there are no remaining references to the transaction, according to LMDB_File.pm, but there clearly are, below.

There may be a better way of doing what I aim: Reuse a read-only transaction, in a read-only environment, across multiple dbRead function calls.

Thanks!

sub dbRead {
 my $db = $_[0]-> _getDbi($_[1]);

  my $txn;

  if(defined $db->{rdOnlyTxn} ) {
    $txn = $db->{rdOnlyTxn};

   ## Results in "Transaction Terminated"
    $txn->renew();
  }
}

sub _getDbi {
 my $env = LMDB::Env->new($dbPath, {
    ...
 });

 if(! $env ) {
   # handle
 }

 my $txn = $env->BeginTxn();

 my $DB = $txn->OpenDB();

 my $err = $txn->commit();
 # Check error

 $envs->{$name} = {env => $env, dbi => $DB->dbi};

 if($dbReadOnly) {
     $envs->{$name}{rdOnlyTxn} = $env->BeginTxn(MDB_RDONLY);
 }

 return  $envs->{$name};
}

Same thing occurs in a version where the new transaction is given to $DB->Txn instead, and the entire $DB reference is stored in $envs.

$envs->{$name} = {env => $env, dbi => $DB->dbi, DB => $DB};

 if($dbReadOnly) {
     $DB->Txn = $env->BeginTxn(MDB_RDONLY);
 }
@hoytech
Copy link
Contributor

hoytech commented Aug 30, 2016

Sorry I've never really used the reset/renew stuff -- hopefully @salortiz can look at this when he has some time available.

As for alternatives, you could just create a new transaction for every dbRead call. I suspect the extra locking/allocation would be lost in the noise of the perl interpreter's slowness -- do you have some reason to believe otherwise, such as high-levels of contention on the reader table lock?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants