Changeset 32582 for main/trunk/greenstone2/perllib/gssql.pm
- Timestamp:
- 2018-11-07T20:44:34+13:00 (5 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
main/trunk/greenstone2/perllib/gssql.pm
r32581 r32582 33 33 use DBI; # the central package for this module used by GreenstoneSQL Plugout and Plugin 34 34 35 #$SIG{INT} = sub { die "Caught a sigint $!" }; 36 #$SIG{TERM} = sub { die "Caught a sigterm $!" }; 37 #$SIG{KILL} = sub { die "Caught a sigkill $!" }; 38 39 40 $SIG{INT} = \&finish_signal_handler; 41 $SIG{TERM} = \&finish_signal_handler; 42 $SIG{KILL} = \&finish_signal_handler; 43 44 sub finish_signal_handler { 45 my ($sig) = @_; # one of INT|KILL|TERM 46 die "Caught a $sig signal $!"; # will call destructor 47 } 35 48 36 ############################## 49 37 … … 75 63 # - db_name (which is the GS3 sitename) 76 64 65 66 67 $SIG{INT} = \&finish_signal_handler; 68 $SIG{TERM} = \&finish_signal_handler; 69 $SIG{KILL} = \&finish_signal_handler; 70 71 sub finish_signal_handler { 72 my ($sig) = @_; # one of INT|KILL|TERM 73 74 if ($_dbh_instance) { # database handle (note, using singleton) still active. 75 76 # TODO: If autocommit wasn't set, then this is a cancel operation. 77 # If we've not disconnected from the sql db yet and if we've not committed 78 # transactions yet, then cancel means we do a rollback here 79 80 if($_dbh_instance->{AutoCommit} == 0) { 81 print STDERR " User cancelled: rolling back SQL database transaction.\n"; 82 $_dbh_instance->rollback(); # will warn on failure, nothing more we can/want to do, 83 } 84 } 85 86 87 die "Caught a $sig signal $!"; # die() will always call destructor (sub DESTROY) 88 } 89 77 90 sub new 78 91 { … … 111 124 # We want to ensure we've closed the db connection in such cases. 112 125 # "Itâs common to call die when handling SIGINT and SIGTERM. die is useful because it will ensure that Perl stops correctly: for example Perl will execute a destructor method if present when die is called, but the destructor method will not be called if a SIGINT or SIGTERM is received and no signal handler calls die." 126 # 113 127 # https://perldoc.perl.org/perlobj.html#Destructors 128 # 129 # https://metacpan.org/pod/release/TIMB/DBI-1.634_50/DBI.pm#disconnect 130 # "Disconnects the database from the database handle. disconnect is typically only used before exitin# g the program. The handle is of little use after disconnecting. 131 # 132 # The transaction behaviour of the disconnect method is, sadly, undefined. Some database systems (such as Oracle and Ingres) will automatically commit any outstanding changes, but others (such as Informix) will rollback any outstanding changes. Applications not using AutoCommit should explicitly call commit or rollback before calling disconnect. 133 # 134 # The database is automatically disconnected by the DESTROY method if still connected when there are no longer any references to the handle. The DESTROY method for each driver should implicitly call rollback to undo any uncommitted changes. This is vital behaviour to ensure that incomplete transactions don't get committed simply because Perl calls DESTROY on every object before exiting. Also, do not rely on the order of object destruction during "global destruction", as it is undefined. 135 # 136 # Generally, if you want your changes to be committed or rolled back when you disconnect, then you should explicitly call "commit" or "rollback" before disconnecting. 137 # 138 # If you disconnect from a database while you still have active statement handles (e.g., SELECT statement handles that may have more data to fetch), you will get a warning. The warning may indicate that a fetch loop terminated early, perhaps due to an uncaught error. To avoid the warning call the finish method on the active handles." 139 # 114 140 sub DESTROY { 115 141 my $self = shift; 116 142 117 143 if (${^GLOBAL_PHASE} eq 'DESTRUCT') { 118 if ($_dbh_instance) { 144 145 if ($_dbh_instance) { # database handle still active. Use singleton handle! 146 147 # THIS CODE HAS MOVED TO finish_signal_handler() WHERE IT BELONGS 148 # If autocommit wasn't set, then this is a cancel operation. 149 # If we've not disconnected from the sql db yet and if we've not committed 150 # transactions yet, then cancel means we do a rollback here 151 152 # if($_dbh_instance->{AutoCommit} == 0) { 153 154 # $_dbh_instance->rollback(); # will warn on failure, nothing more we can/want to do, 155 # # don't do a die() here: possibility of infinite loop and we still want to disconnect 156 # } 157 158 # Either way, we're now finally ready to disconnect as is required for premature 159 # termination too 119 160 print STDERR "XXXXXXXX Global Destruct: Disconnecting from database\n"; 120 161 $_dbh_instance->disconnect or warn $_dbh_instance->errstr; … … 182 223 #my $self= shift (@_); # singleton method doesn't use self, but callers don't need to know that 183 224 my ($params_map) = @_; 184 225 226 if($params_map->{'verbosity'}) { 227 if(!defined $params_map->{'autocommit'}) { 228 print STDERR " Autocommit parameter not defined\n"; 229 } 230 if($params_map->{'autocommit'}) { 231 print STDERR " SQL DB UNDO SUPPORT OFF.\n"; 232 } else { 233 print STDERR " SQL DB UNDO SUPPORT ON.\n"; 234 } 235 } 236 185 237 return $_dbh_instance if($_dbh_instance); 186 238 … … 217 269 print STDERR "\nAssuming the mysql server has been started with: --character_set_server=utf8mb4\n" if $db_driver eq "mysql"; 218 270 } 271 272 # DBI AutoCommit connection param is on/1 by default, so if a value for this is not defined 273 # as a method parameter to _get_connection_instance, then fallback to the default of on/1 274 my $autocommit = (defined $params_map->{'autocommit'}) ? $params_map->{'autocommit'} : 1; 219 275 220 276 my $dbh = DBI->connect("$connect_str", $db_user, $db_pwd, … … 223 279 PrintError => 1, # on by default, but being explicit 224 280 RaiseError => 0, # off by default, but being explicit 225 AutoCommit => 1, # on by default, but being explicit281 AutoCommit => $autocommit, 226 282 mysql_enable_utf8mb4 => 1 # tells MySQL to use UTF-8 for communication and tells DBD::mysql to decode the data, see https://stackoverflow.com/questions/46727362/perl-mysql-utf8mb4-issue-possible-bug 227 283 }); … … 273 329 my $self= shift (@_); 274 330 331 # TODO: if AutoCommit was off, meaning transactions were on/enabled, 332 # then here is where we commit our one long transaction. 333 # https://metacpan.org/pod/release/TIMB/DBI-1.634_50/DBI.pm#commit 334 my $rc = 1; 335 275 336 $ref_count--; 276 337 if($ref_count == 0) { 338 # Only commit transaction when we're about to disconnect, not before 339 # If autocommit was on, then we'd have committed after every db operation, so nothing to do 340 $rc = $self->do_commit_if_on(); 341 277 342 $self->force_disconnect_from_db(); 278 } 343 } 344 345 return $rc; 346 } 347 348 sub do_commit_if_on { 349 my $self= shift (@_); 350 my $dbh = $self->{'db_handle'}; 351 352 my $rc = 1; # return code: everything went fine, regardless of whether we needed to commit 353 # (AutoCommit on or off) 354 355 # https://metacpan.org/pod/release/TIMB/DBI-1.634_50/DBI.pm#commit 356 if($dbh->{AutoCommit} == 0) { 357 print STDERR " Committing transaction to SQL database now.\n" if $self->{'verbosity'}; 358 $rc = $dbh->commit() or warn("SQL DB COMMIT FAILED: " . $dbh->errstr); # important problem 359 # worth embellishing error message 360 } 361 # If autocommit was on, then we'd have committed after every db operation, so nothing to do 362 363 return $rc; 279 364 } 280 365 … … 429 514 $dbh->do("drop table $table");# || warn("@@@ Couldn't delete $table"); 430 515 } 516 517 # TODO Q: commit here, so that future select statements work? 518 # See https://metacpan.org/pod/release/TIMB/DBI-1.634_50/DBI.pm#Transactions 431 519 } 432 520
Note:
See TracChangeset
for help on using the changeset viewer.