$updateStmt =
$this->
getUpdateStatement($sessionId,
$data,
$maxlifetime);
$updateStmt->
execute();
// When MERGE is not supported, like in Postgres < 9.5, we have to use this approach that can result in
// duplicate key errors when the same session is written simultaneously (given the LOCK_NONE behavior).
// We can just catch such an error and re-execute the update. This is similar to a serializable
// transaction with retry logic on serialization failures but without the overhead and without possible
// false positives due to longer gap locking.
if (!
$updateStmt->
rowCount()) { try { $insertStmt =
$this->
getInsertStatement($sessionId,
$data,
$maxlifetime);
$insertStmt->
execute();
} catch (\PDOException
$e) { // Handle integrity violation SQLSTATE 23000 (or a subclass like 23505 in Postgres) for duplicate keys
if (str_starts_with($e->
getCode(), '23'
)) { $updateStmt->
execute();
} else { throw $e;
} } } } catch (\PDOException
$e) {