Search code examples
phpmysqlpdolast-insert-id

Is PDO::lastInsertId() in multithread single connection safe?


I read some threads here about PDO::lastInsertId() and its safety. It returns last inserted ID from current connection (so it's safe for multiuser app while there is only one connection per user/script run).

I'm just wondering if there is a possibility to get invalid ID if there is only one DB connection per one long script (lots of SQL requests) in multicore server system? The question is more likely to be theoretical.

I think PHP script run is linear but maybe I'm wrong.


Solution

  • PDO itself is not thread safe. You must provide your own thread safety if you use PDO connections from a threaded application.

    The best, and in my opinion the only maintainable, way to do this is to make your connections thread-private.

    If you try to use one connection from more than one thread, your MySQL server will probably throw Packet Out of Order errors.

    The Last Insert ID functionality ensures multiple connections to MySQL get their own ID values even if multiple connections do insert operations to the same table.

    For a typical php web application, using a multicore server allows it to handle more web-browser requests. A multicore server doesn’t make the php programs multithreaded. Each php program, to handle each web request, allocates is own PDO connections. As you put it, each php script run is “linear”. The multiple cores allow multiple scripts to run at the same time, but independently.

    Last Insert ID is designed to be safe for that scenario.

    Under some circumstances a php program may leave the MySQL connection open when it's done so another php program may use it. This is is called a persistent connection or connection pooling. It helps performance when a web site has many users connecting to it. The generic term for a reusable connection is "serially reusable resource.*

    Some php programs may use threads. In this case the program must avoid allowing more than one thread to use the same connection at the same time, or get the dreaded Packet Out of Order errors.

    (Virtually all machines have multiple cores.)