Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

Ligonsker's avatar

How to check if values exist and prevent others from inserting these values at the same time?

I have an array of values that I want to insert into a DB column:

$values = ['1', '32', '101'];

How to insert these values only if none of them exist in the table, and also prevent others from inserting them while I'm checking it?

0 likes
2 replies
LaryAI's avatar
Level 58

One solution is to use a database transaction with a SELECT FOR UPDATE statement to lock the rows being checked and prevent other processes from inserting the same values at the same time. Here's an example using Laravel's query builder:

DB::transaction(function () use ($values) {
    // Lock the rows being checked
    DB::table('my_table')->whereIn('my_column', $values)->sharedLock()->get();

    // Check if any of the values exist
    $existingValues = DB::table('my_table')->whereIn('my_column', $values)->pluck('my_column')->toArray();

    // Insert the values that don't exist
    $newValues = array_diff($values, $existingValues);
    if (!empty($newValues)) {
        DB::table('my_table')->insert(array_map(function ($value) {
            return ['my_column' => $value];
        }, $newValues));
    }
});

Explanation:

  1. The DB::transaction method wraps the database operations in a transaction, which ensures that either all of the operations succeed or none of them do. This is important to prevent race conditions where multiple processes try to insert the same values at the same time.

  2. The whereIn method is used to select the rows that match any of the values in the $values array. The sharedLock method is called to lock the selected rows for reading, which prevents other processes from inserting the same values until the transaction is committed or rolled back.

  3. The pluck method is used to extract the values of the my_column column from the selected rows. The toArray method is called to convert the collection to a plain array.

  4. The array_diff function is used to find the values in $values that don't exist in $existingValues.

  5. The array_map function is used to transform the $newValues array into an array of associative arrays that can be inserted into the database using the insert method.

Note that this solution assumes that the my_column column has a unique constraint or index to prevent duplicate values. If this is not the case, you may need to add a unique constraint or index to the column or use a different approach to prevent duplicates.

Ligonsker's avatar

Can someone explain if this is correct? The bot says:

"The sharedLock method is called to lock the selected rows for reading".

But what if these rows don't exist? There is nothing to lock so it looks like it won't do the job?

Please or to participate in this conversation.