Od 15. do 21.4. slevy 20 až 80% v sekci C/C++. Když ne teď, tak kdy?
Vyšlehej si extra vědomosti! Až 100% bodů na prémiový obsah zdarma! Více zde

Diskuze: PHP: SQLite3::exec(): database is locked - nefunkční pouze pro určité příkazy

Aktivity (1)
Avatar
Jakub Ransdorf:22. února 23:37

Mám problém s hláškou SQLite3::exec(): database is locked v PHP programu. Nejsem schopný přijít na její řešení. V PHP používám databázi SQLite3. Chybová hláška se zobrazuje při použití SQL příkazu UPDATE, ale předchozí příkazy o pár řádků výše bez problému fungují. Implementace je taková, aby všechno nějak fungovalo (vím, že to není ideální), je to můj první program v php, např. PDO si tam dodělám pak. Jde mi teď primárně o to, přijít na to, jak této chybě zabránit, případně najít příčinu proč vzniká...

<?php
session_start();
if ((isset($_SESSION["id"])===false) or ($_SESSION["id"] == ""))
{
    header("Location: index.php");
    die();
}
$db = new SQLite3("tretrys.sqlite", SQLITE3_OPEN_READWRITE);
$pocet_zavodu = $db->querySingle("SELECT COUNT (*) FROM zavody");
$pocet_zavodu++;
$zavod = $_COOKIE["rozsah_min"];
$user = "";
if (isset($_SESSION["id"]))
{
    $user = $_SESSION["id"];
}
else
{
    header("Location: index.php");
    die();
}

$query_all_to_view = $db->query("SELECT id, datum FROM zavody ORDER BY datum ASC");
while ($row = $query_all_to_view -> fetchArray (SQLITE3_ASSOC)) {
    $zav = (int)$row["id"];
    Kontrola_zmeny_databaze($zav, $user);

}

function Kontrola_zmeny_databaze($zavod, $user){
     $db = new SQLite3('tretrys.sqlite', SQLITE3_OPEN_READWRITE);
     $test_is_in = $db->querySingle("SELECT COUNT(id_zavodu) FROM uzivatel_jede_na_zavod WHERE id_zavodu='$zavod' AND username='$user'");
     if($test_is_in==0)
     {
        $db->exec("INSERT INTO uzivatel_jede_na_zavod(username,id_zavodu,startovne_uziv, ubytovani_uziv, doprava_uziv, beru_uziv, pocet_mist) VALUES('$user','$zavod','0','0','0','0','0')");
    }

    $startovne = $db->querySingle("SELECT startovne_uziv FROM uzivatel_jede_na_zavod WHERE id_zavodu='$zavod' AND username='$user'");
    $ubytovani = $db->querySingle("SELECT ubytovani_uziv FROM uzivatel_jede_na_zavod WHERE id_zavodu='$zavod' AND username='$user'");
    $doprava = $db->querySingle("SELECT doprava_uziv FROM uzivatel_jede_na_zavod WHERE id_zavodu='$zavod' AND username='$user'");
    $beru_auto = $db->querySingle("SELECT beru_uziv FROM uzivatel_jede_na_zavod WHERE id_zavodu='$zavod' AND username='$user'");
    $id=$zavod;
    $zavod_def = $zavod - $_COOKIE["rozsah_min"];

                    if (isset($_GET["start_check$zavod_def"]))
                    {
                        $db->exec("UPDATE uzivatel_jede_na_zavod SET startovne_uziv = '1' WHERE id_zavodu = '$id' AND username='$user'");
                    }
                    else
                    {
                       $db->exec("UPDATE uzivatel_jede_na_zavod SET startovne_uziv = '0' WHERE id_zavodu = '$id' AND username='$user'");
                    }

                    if (isset($_GET["ubyt_check$zavod_def"]))
                    {
                          $db->exec("UPDATE uzivatel_jede_na_zavod SET ubytovani_uziv = '1' WHERE id_zavodu = '$id' AND username='$user'");
                    }
                    else
                    {
                        $db->exec("UPDATE uzivatel_jede_na_zavod SET ubytovani_uziv = '0' WHERE id_zavodu = '$id' AND username='$user'");
                    }

                    $hodnota_predchozi = $db->querySingle("SELECT doprava_uziv FROM uzivatel_jede_na_zavod  WHERE id_zavodu = '$id' AND username='$user'");
                    if (isset($_GET["dopr_check$zavod_def"]))
                    {

                        $db->exec("UPDATE uzivatel_jede_na_zavod SET doprava_uziv = '1' WHERE id_zavodu = '$id' AND username='$user'");
                        if ($hodnota_predchozi == 0)
                            $db->exec("UPDATE zavody SET php_calc=php_calc-1 WHERE id=$id");
                    }
                    else
                    {
                       $db->exec("UPDATE uzivatel_jede_na_zavod SET doprava_uziv = '0' WHERE id_zavodu = '$id' AND username='$user'");
                       if ($hodnota_predchozi == 1)
                            $db->exec("UPDATE zavody SET php_calc=php_calc+1 WHERE id=$id");

                    }
                    if (isset($_GET["beru_auto$zavod_def"]))
                    {
                          $db->exec("UPDATE uzivatel_jede_na_zavod SET beru_uziv = '1' WHERE id_zavodu = '$id' AND username='$user'");
                          if (isset($_GET["pocet_mist$zavod_def"]))
                    {
                        $pocet_mist_v_aute = $db->querySingle("SELECT pocet_mist FROM uzivatel_jede_na_zavod WHERE id_zavodu='$zavod' +1 AND username='$user'");
                        $this_calc_now = $db->querySingle("SELECT php_calc FROM zavody WHERE id= '$zavod' +1");
                        $new_pocet = $_GET["pocet_mist$zavod_def"];
                        $rozdil =  $new_pocet - $pocet_mist_v_aute + $this_calc_now;

                        $db->exec("UPDATE zavody SET php_calc = '$rozdil' WHERE id='$id'");
                        $db->exec("UPDATE uzivatel_jede_na_zavod SET pocet_mist = '$new_pocet' WHERE id_zavodu = '$id' AND username ='$user'");


                    }
                    }
                    else
                    {
                        $pocet_mist_v_aute = $db->querySingle("SELECT pocet_mist FROM uzivatel_jede_na_zavod WHERE id_zavodu='$zavod' +1 AND username='$user'");
                        $this_calc_now = $db->querySingle("SELECT php_calc FROM zavody WHERE id= '$zavod' +1");
                        $new_pocet = 0;
                        $rozdil =  $new_pocet - $pocet_mist_v_aute + $this_calc_now;
                        $db->exec("UPDATE zavody SET php_calc = '$rozdil' WHERE id='$id'");
                        $db->exec("UPDATE uzivatel_jede_na_zavod SET beru_uziv = '0' WHERE id_zavodu = '$id'");
                        $db->exec("UPDATE uzivatel_jede_na_zavod SET pocet_mist ='0' WHERE id_zavodu = '$id' AND username ='$user'");
                    }


    //$db->exec("UPDATE zavody SET php_calc = 0");

}

header("Location: prehled.php");
die();
?>

Chybová hláška v prohlížeči vypadá takto:

Warning: SQLite3::exec(): database is locked in /home/ransdjak/www/tes­t/sem/add_user_va­lues_to_db.php on line 48

Zkusil jsem: Již jsem zkoušel nastavit souboru maximální práva, ale bez úspěchu.

Mám teď dvě myšlenky, kde by mohl být problém, ale dál se nejsem schopný dostat:

  1. problém s SQLite3 databází, která je přetížená, je tam příliš připojení, neuzavřené spojení nebo nco takového
  2. problém s proměnou id, která je ve skutečnosti hodnotou row["id"] z cyklu, který vytvořil dotaz SQLite3 databáze.

Chci docílit: Chci jen provést SQL příkaz Update z příkladu výše.

 
Odpovědět 22. února 23:37
Avatar
Odpovídá na Jakub Ransdorf
Tomáš Novotný:23. února 9:40

ahoj, problém je patrně v tom, že máš 2x $db = new SQLite3('tretrys­.sqlite', SQLITE3_OPEN_RE­ADWRITE);
jednou v root scope a jednou ve funkci Kontrola_zmeny_da­tabaze

Nahoru Odpovědět 23. února 9:40
∞ ... the exact amount of possibilities how to deal with the situation ... so by calm, your solution is one of many
Avatar
Tomáš Novotný:23. února 9:59

možná řešení v principu... zda jsou všechna možná/vhodná pro aktuální potřeby s použitím SQLite si už zhodnoť...

  1. předat si $db z root scope do funkce... tj. ve funkci nevytvářet nový objekt $db ale předat si ho parametrem
  2. $db v root scope nastavit jen pro čtení ne čtení a zápis, ve funkci nechat čtení i zápis
  3. použití globální $db
  4. na některém z vhodných míst provést unset($db)
Akceptované řešení
+20 Zkušeností
Řešení problému
Nahoru Odpovědět 23. února 9:59
∞ ... the exact amount of possibilities how to deal with the situation ... so by calm, your solution is one of many
Avatar
Jakub Ransdorf:23. února 20:31

Díky moc! Nejdřív jsem zkusil definovat pro čtení první a druhou pro čtení a zápis, to nešlo, ale předání parametrem funguje.

 
Nahoru Odpovědět 23. února 20:31
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 4 zpráv z 4.