in reply to Inserting into several linked MySQL tables.

If all tables are using the InnoDB engine, then you can certainly use transactions. The way to do this in DBD::mysql is to turn AutoCommit off, then issue your statements. You can optionally send an explicit "BEGIN WORK" statement, but you don't have to. (I do, but that's cause I'm paranoid.) When you're ready to commit, issue a $dbh->commit() to commit or $dbh->rollback(), if you're rolling back. (Those functions are documented in the DBI documentation.)

If any of your tables are non-InnoDB, then you would have to issue a LOCK TABLES statement, pairing that with the appropriate UNLOCK TABLES at the appropriate time. The big issue with this is that you don't have any method to rollback if you run into a problem. The other problem is that you have a lock on those tables, which means all other attempts to modify the tables (and possibly even read, depending on the lock) are blocked until such time as you release the lock. Because of this, you can enter a race condition where process 1 locks tables A and B and process 2 locks tables B and A. If they run at the same time, process 1 locks table A, then tries to get a lock on table B. But, process 2 already locked table B and is trying to get a lock on table A. This is called deadlock, which is bad.

As for the process by which you do this, you would use the $dbh->{mysql_insertid} to find the last inserted id. (This is documented in the DBD::mysql documentation.) This is a step up from, say Oracle or Sybase, where you have to explicitly issue a SELECT statement to retrieve this information.


My criteria for good software:
  1. Does it work?
  2. Can someone else come in, make a change, and be reasonably certain no bugs were introduced?

Replies are listed 'Best First'.
Re^2: Inserting into several linked MySQL tables.
by mpeppler (Vicar) on Sep 27, 2005 at 18:40 UTC
    Actually DBD::Sybase will honor the $dbh->last_insert_id() method in a lot of cases.

    Michael