PDO insert data through transaction method I have an import books function to insert more than 5000 rows at once, I did some research and did this one but some other places I saw a different kind of methods to insert without looping and execute this. is my code got any trouble with the performance of app

public function importBooks($data, $no_of_rows)
{
    try {
        // Start transaction
        $this-&gt;db-&gt;beginTransaction();

        // Init query
        $this-&gt;db-&gt;query('INSERT INTO books_pre (title, author, publication, container, tmp_no, created_by, created_at) VALUES (:title, :author, :publication, :container, :tmp_no, :created_by, now())');

        for ($i=2; $i&lt;=$no_of_rows; $i++) {
            // Bind values
            $this-&gt;db-&gt;bind(':title', $data[$i]['B']);
            $this-&gt;db-&gt;bind(':author', $data[$i]['C']);
            $this-&gt;db-&gt;bind(':publication', $data[$i]['D']);
            $this-&gt;db-&gt;bind(':container', $data[$i]['E']);
            $this-&gt;db-&gt;bind(':tmp_no', $data[$i]['A']);
            $this-&gt;db-&gt;bind(':created_by', $_SESSION['user_id']);

            // Execute query
            if (!$this-&gt;db-&gt;execute()) {
                return false;
            }
        }
        // Commit data
        $this-&gt;db-&gt;commitTransaction();
    } catch (Exception $e) {
        $this-&gt;db-&gt;cancelTransaction();
        echo "Failed: " . $e-&gt;getMessage();
    }
}
Your code is all right from the performance point of view. 

But again, you are doing the double work with your homegrown wrapper. For the life of me I won't understand a wrapper that makes your life harder.

So again, a code with vanilla PDO instance in $this-&gt;db

$stmt = $this-&gt;db-&gt;prepare('INSERT INTO books_pre 
    (title, author, publication, container, tmp_no, created_by, created_at) 
    VALUES (:B, :C, :D, :E, :A, :user_id, now())');

try {
    $this-&gt;db-&gt;beginTransaction();
    foreach(data as $i =&gt; $row) {
        // skip the first two lines
        if ($i == 0 or $i == 1) {
            continue;
        }
        $row['user_id'] = $_SESSION['user_id'];
        $stmt-&gt;execute($row);
    }
    $this-&gt;db-&gt;commit();
} catch (Exception $e) {
    $this-&gt;db-&gt;rollback();
    throw new $e;
}


Given you already have an associative array we can use its keys as placeholder names. 

PDO's execute() method can accept an associative array with data, for example

$stmt = $pdo-&gt;prepare("SELECT * FROM t WHERE id=:id");
$stmt-&gt;execute(['id'] =&gt; $id);


As you can see, we are sending an array directly into execute(), which  keys that must match placeholder names. Given your array already have keys, I just used them as placeholder names in the query. 

However, it'a a matter of taste and you can keep use your bind() calls instead. 

An important note, there should be no such thing like echo "Failed: " in your code. Always just throw an error and let it be echoed by PHP.

On a side note, a comment like this

    // Start transaction
    $this-&gt;db-&gt;beginTransaction();


makes very little sense. Do not write comments that just duplicate a code below. Use comments to explain something not that obvious.