From b317fbd689b5ef362192025f797da0d451105f8e Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Mon, 7 Jan 2013 01:37:28 +0000 Subject: [PATCH] wip, transaction fixup --- cgi-auth-hybrid.pm | 49 ++++++++++++++++++++++++++++++---------------- commit-test.pl | 25 +++++++++++++++++++++++ test.cgi | 2 -- 3 files changed, 57 insertions(+), 19 deletions(-) create mode 100755 commit-test.pl diff --git a/cgi-auth-hybrid.pm b/cgi-auth-hybrid.pm index f22083a..0617881 100644 --- a/cgi-auth-hybrid.pm +++ b/cgi-auth-hybrid.pm @@ -209,14 +209,14 @@ sub _dbopen ($) { die "$dsn $! ?" unless $dbh; $v->{Dbh} = $dbh; - $dbh->do("BEGIN"); - eval { - $dbh->do("CREATE TABLE $v->{S}{assocdb_table} (". - " associdh VARCHAR PRIMARY KEY,". - " username VARCHAR,". - " last INTEGER NOT NULL". - ")"); + $r->_db_transaction(sub { + $dbh->do("CREATE TABLE $v->{S}{assocdb_table} (". + " associdh VARCHAR PRIMARY KEY,". + " username VARCHAR,". + " last INTEGER NOT NULL". + ")"); + }); }; return $dbh; } @@ -228,6 +228,29 @@ sub disconnect ($) { $dbh->disconnect(); } +sub _db_transaction ($$) { + my ($r, $fn) = @_; + my $retries = 10; + my $rv; + my $dbh = $v->{Dbh}; + for (;;) { + if (!eval { + $rv = $fn->(); + 1; + }) { + { local ($@); $dbh->rollback(); } + die $@; + } + if (eval { + $dbh->commit(); + 1; + }) { + return $rv; + } + die $@ if !--$retries; + } +} + #---------- request object methods ---------- sub new_request { @@ -550,16 +573,8 @@ sub check_divert ($) { return $r->{Divert}; } my $dbh = $r->{Dbh}; - $dbh->do("BEGIN"); - if (!eval { - $divert = $r->_check_divert_core(); - 1; - }) { - $dbh->do("ABORT"); - die $@; - } - $r->{Divert} = $divert; - $dbh->do("COMMIT"); + $r->{Divert} = $r->_db_transaction(sub { $r->_check_divert_core(); }); + $dbh->commit(); return $divert; } diff --git a/commit-test.pl b/commit-test.pl new file mode 100755 index 0000000..69a0640 --- /dev/null +++ b/commit-test.pl @@ -0,0 +1,25 @@ +#!/usr/bin/perl -w + +use warnings; +use strict; +use DBI; + +my $dsn = "dbi:SQLite:dbname=test.db"; +my $dbh = DBI->connect($dsn, '','', { + AutoCommit => 0, RaiseError => 1, + }); + +foreach my $v (@ARGV) { + if (!eval { + if ($v eq 'bw') { $dbh->begin_work or die; } + elsif ($v eq 'rb') { $dbh->rollback or die; } + elsif ($v eq 'ci') { $dbh->commit or die; } + elsif ($v eq 'dc') { $dbh->disconnect or die; } + elsif ($v eq 'ct') { $dbh->do('CREATE TABLE t (f TEXT)') or die; } + elsif ($v eq 'i') { $dbh->do('INSERT INTO t VALUES ("x")') or die; } + else { die; } + 1; + }) { + warn $@; + } +} diff --git a/test.cgi b/test.cgi index b929551..c869327 100755 --- a/test.cgi +++ b/test.cgi @@ -7,8 +7,6 @@ use CGI::Auth::Hybrid; my $dump = "$ENV{'CAHTEST_HOME'}/dump"; -#require 'cgi-auth-hybrid.pm'; - my $verifier = CGI::Auth::Hybrid->new_verifier( assocdb_path => "$dump/assoc.db", username_password_ok => sub { my ($c,$r,$u,$p)=@_; return $p eq 'sesame'; }, -- 2.30.2