You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

循环内执行SQLite Insert查询报错:Database is locked

Fixing SQLite "Database is locked" Error in Your For Loop Insert

Hey there, let's tackle that "Database is locked" error you're hitting on line 904 in your try block's for loop. This is a super common gotcha with SQLite—especially when doing batch inserts like you are with your product list. Here's what's likely causing it and how to fix it step by step:

1. You're probably mismanaging database connections

SQLite is a file-based database, so it gets grumpy if connections are left open, or if you're spawning new connections inside your loop (which creates conflicting locks). If you're opening a new connection every time you run an insert in the loop, that's almost certainly the issue.

Fix:

  • Open your database connection once before the loop starts, not inside it.
  • Always close the connection when you're done (use a finally block to guarantee this, even if an error happens).
  • Reuse the same prepared statement for every insert in the loop (way faster and avoids lock issues too).

2. You're not using transactions properly

If you're running individual inserts without wrapping them in a transaction, SQLite locks the database for each single write—this adds up fast in a loop and causes lock conflicts. Even worse, if a previous insert started a transaction that never got committed/rolled back, the lock stays stuck.

Fix:

Wrap your entire loop in a single transaction. This batches all your inserts into one atomic operation, which is way faster and eliminates lock contention. Here's a modified version of your code structure to show this:

try {
    // Open connection ONCE before the loop
    $db = new PDO('sqlite:your_database_file.db');
    $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    // Start a transaction
    $db->beginTransaction();

    // Prepare your insert statement ONCE
    $insertStmt = $db->prepare("INSERT INTO your_table_name (product, cname, total, paid, bill_id, customer_id) 
                               VALUES (?, ?, ?, ?, ?, ?)");

    // Loop through products and execute the prepared statement
    foreach ($_REQUEST['Products'] as $product) {
        // Bind your values (adjust based on your actual columns!)
        $insertStmt->bindValue(1, $product);
        $insertStmt->bindValue(2, $_REQUEST['cname']);
        $insertStmt->bindValue(3, $_REQUEST['totalAmt']);
        $insertStmt->bindValue(4, $_REQUEST['paidAmt']);
        $insertStmt->bindValue(5, $_REQUEST['billId']);
        $insertStmt->bindValue(6, $_REQUEST['customer_id']);

        $insertStmt->execute(); // This runs the insert without re-locking every time
    }

    // Commit all inserts at once
    $db->commit();
} catch (PDOException $e) {
    // Rollback if anything goes wrong
    if (isset($db)) $db->rollBack();
    echo "Error: " . $e->getMessage();
} finally {
    // Close the connection no matter what
    $db = null;
}

3. Check for external locks

Sometimes the lock isn't even from your script! If you have a database viewer (like DB Browser for SQLite) open, or another instance of your script running in the background, it can hold the lock on the SQLite file.

Fix:

  • Close any other programs accessing the SQLite database file.
  • If your script crashed recently, look for leftover temporary files (like your_db.db-journal) in the same folder as your database—delete these if you're sure no other process is using the DB (they're supposed to be cleaned up automatically, but sometimes get stuck).

4. Stop using multiple database handles

If you're creating multiple PDO or SQLite3 instances pointing to the same database file in your script, that can cause lock conflicts, especially if they're writing at the same time.

Fix:

Reuse a single database handle throughout your entire script instead of creating new ones in functions or loops.

Quick check for line 904

Double-check that line 904 isn't opening a new database connection or failing to commit a pending transaction. That's the spot where the lock is being triggered, so it's likely related to how you're handling the connection/transaction there.

内容的提问来源于stack exchange,提问作者Waeez

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 07:08:14