in reply to Re: run 2 query mysql
in thread run 2 query mysql

$DBH->do("BEGIN"); # explicitly start a new transaction # this overrides autocommit setting # ... $DBH->do("COMMIT"); #end transaction, this is the "expensive part" ti +mewise

That way seems to be at least unportable, if not wrong. Why don't you follow the usual DBI procedure documented in DBD::mysql, DBD::MariaDB (with nearly exactly the same wording), Transactions of DBI and in begin_work of DBI? At least, manually issuing BEGIN and COMMIT commands bypasses anything DBI knows about transactions.

Try::Tiny from the example in Transactions of DBI can easily be replaced by eval, and using the standard DBI methods works with all DBI-supported databases capable of transactions, not just with MySQL and MariaDB:

my $dbh=DBI->connect('dbi:...', 'user', 'pass', { RaiseError => 1, Aut +oCommit => 1, ... }); $dbh->begin_work(); # if this fails, you have tried to nest transactio +ns. unless ( eval { change_some_stuff($dbh); change_more_stuff($dbh); $dbh->commit(); 1; } ) { warn "Rolling back because: $@"; eval { $dbh->rollback() }; } # At this point, either all changes or no changes have happened in the + database.

Alexander

--
Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)

Replies are listed 'Best First'.
Re^3: run 2 query mysql
by Marshall (Canon) on Mar 04, 2019 at 20:31 UTC
    Well as far as portability goes, you are correct in that BEGIN is not technically an offical SQL statement, but rather an extremely common alias for the standard SQL command "START TRANSACTION". I am unaware of a DB that doesn't have the BEGIN alias. But I guess there could be such a critter out there. COMMIT is a standard SQL command.

    I am certainly not an SQL guru and most of my DB code is fairly straightforward. The Perl DBI is fantastic in how easily command line SQL can be converted into Perl code. I tend to debug my SQL operations from the SQL command line and then transfer that knowledge into Perl DBI code. From that perspective, using BEGIN and COMMIT makes some sense and fits with my work flow. However as youi point out, there are DBI method calls for these SQL commands. I suspect that there is some efficiency to using them. However for me, a typical transaction is 500 operations and that would make no difference.

    Error handling is a big, a very big subject,
    I normally use the option RaiseError=>1 in the connect. If a fatal SQL error occurs, the program bombs. In a case like was posted, if a fatal error happens, the transaction fails. No rollback is needed. When the connection to the DB is lost, the DB will throw away the pending transaction (because COMMIT never occured).

    When you go to the trouble of trapping an error (as you show), You have to explictly do something to rollback or otherwise cancel the pending transaction. Then the question becomes "Now What?". If there is no answer to that question, then trapping the error doesn't matter.

    I have applications that are completely "restartable" as long as each transaction either fully works or doesn't work, the application can just be run again from scratch with an updated input file. Of course in some instance like shown, where a "delta" is being applied to the DB, that simple approach won't work. Lots of possilities that seemed to be outside the scope of the OP's question...