SQLite is Locked – MySQL – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu

SQLite is Locked – MySQL – Fórum – Programujte.comSQLite is Locked – MySQL – Fórum – Programujte.com

 

Martin
~ Anonymní uživatel
1602 příspěvků
5. 10. 2014   #1
-
0
-

Dobrý den,
dal jsem se do programovaní v c# a bojuji s databází SQLite. Mám vytvořených několik příkazů k přístupům ale u jednoho jediného mě to padá a píše chybu "Additional information: database is locked" Prošel jsem poctivě všechny příkazy otevření databáze a všechny jsou zavřeny, ani použití usigu mě nepomohlo (podle netu). Je to chyba, která se objevuje nahodile, jednou projde třeba 10x po sobě a pak zase 5x ne, je to nepříjemná chyba při které padá celý program a nevím jak ji podchytit, zachytit nebo jinak ošetřit.

        public void UpdateZapis(String druzstvo, String okres, bool kategorie, Double hodnoceniL, Double hodnoceniP, Double hodnoceni)
        {

            string cas = "12:00:00";

            getConnection().Open();

            using (SQLiteCommand command = new SQLiteCommand("UPDATE TabulkaUtok SET Lterc=@param1, Pterc=@param2, Cas=@param3, Hodnoceni=@param4 WHERE Druzstvo=@param5 AND Okres=@param6 AND Kategorie=@param7", this.connection))
            {
                command.Parameters.Add(new SQLiteParameter("@param1", hodnoceniL));
                command.Parameters.Add(new SQLiteParameter("@param2", hodnoceniP));
                command.Parameters.Add(new SQLiteParameter("@param3", cas));
                command.Parameters.Add(new SQLiteParameter("@param4", hodnoceni));
                command.Parameters.Add(new SQLiteParameter("@param5", druzstvo));
                command.Parameters.Add(new SQLiteParameter("@param6", okres));
                command.Parameters.Add(new SQLiteParameter("@param7", kategorie));
                command.ExecuteNonQuery();
            }
            getConnection().Close();
            VypocetPoradi();
        }

Jsem v koncích a proto vás prosím o radu. Děkuji předem

Nahlásit jako SPAM
IP: 91.187.49.–
Kit+15
Guru
5. 10. 2014   #2
-
0
-

#1 Martin
Otevírej tu databázi jen na jednom místě a vytvoř z ní objekt. Ten pak předávej objektům, které s ní mají nějak pracovat.

Nahlásit jako SPAM
IP: 2a00:1028:83a0:37a6:221:5...–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
Martin
~ Anonymní uživatel
1602 příspěvků
5. 10. 2014   #3
-
0
-

#2 Kit
Databáze se mě otvírá dobře, zkoušel jsem tam dat 

            MessageBox.Show(getConnection().State.ToString());
            getConnection().Open();
            MessageBox.Show(getConnection().State.ToString());

a před otevřením je vždy řádně uzavřena. Při uměle vytvořené chybě se špatným uzavřením vyhodí chybu v příkazu open() a né až v příkazu command.ExecuteNonQuery().

Nahlásit jako SPAM
IP: 91.187.49.–
Kit+15
Guru
5. 10. 2014   #4
-
0
-

#3 Martin
Nepochopil jsi to. Otevírej databázi jen jednou a objektům předávej už otevřenou databázi v parametrech. Tím ti odpadne neustálé otevírání/zavírání a aplikace se tím zrychlí.

Nahlásit jako SPAM
IP: 2a00:1028:83a0:37a6:221:5...–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
Martin
~ Anonymní uživatel
1602 příspěvků
5. 10. 2014   #5
-
0
-

#4 Kit
Aha, už. To ale budu muset přepsat celý program. Něco jiného tě nenapadne čím by to mohlo byt nebo jak tu chybu ošetřit?

Nahlásit jako SPAM
IP: 91.187.49.–
Kit+15
Guru
5. 10. 2014   #6
-
0
-

#5 Martin
Tak to nevím. Dělám to vždy touhle injekcí - lépe se mi to testuje.

SQLite nesnáší souběžnou práci z více vláken, protože ovladač nemá jak zjistit, že je DB otevřena z jiného vlákna. Není to náhodou tento problém? V tom případě bych doporučil databázové připojení dát do samostatného vlákna (kritické sekce), do kterého budeš přesměrovávat všechny požadavky.

Nahlásit jako SPAM
IP: 2a00:1028:83a0:37a6:221:5...–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
Martin
~ Anonymní uživatel
1602 příspěvků
5. 10. 2014   #7
-
0
-

#6 Kit
Jak jsem psal, zkusil jsem schválně nezavřít DB jinde a to mě hodí chybu už v getConnection().Open(). Takže by mělo být vše řádně zavřené tím pádem zajištěn jen jeden přístup do DB. Děkuji moc za rady, zkusím to přepsat na otevření/zavření jen jednou ale obávám se, že pes bude zakopaný jinde. Ještě jednou děkuji, už jsem totiž fakt v koncích.

Nahlásit jako SPAM
IP: 91.187.49.–
Kit+15
Guru
5. 10. 2014   #8
-
0
-

#7 Martin
Pokud mezi sebou soupeří více vláken, tak to nepomůže. Soubory se totiž nezavírají ihned, ale při úklidu. Sousední vlákna o tom však neví. Proto je důležité, aby se s databází SQLite pracovalo pouze v jednom vlákně.

Je to specifikum pro všechny souborové databáze. Dokáží si to ohlídat mezi procesy, ale ne mezi vlákny jednoho procesu.

Nahlásit jako SPAM
IP: 2a00:1028:83a0:37a6:221:5...–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
Martin
~ Anonymní uživatel
1602 příspěvků
5. 10. 2014   #9
-
0
-

#8 Kit
Ok, zkusím dořešit a dám vědět jak to dopadlo. Děkuji za pomoc.

Nahlásit jako SPAM
IP: 91.187.49.–
Kit+15
Guru
5. 10. 2014   #10
-
0
-

#9 Martin
Jen tak na okraj: Nevěř informaci o zamykání jednotlivých záznamů. Databáze SQLite se při modifikaci vždy zamyká celá. To ji diskvalifikuje z úloh, ve kterých se velmi často zapisuje z různých procesů.

Nahlásit jako SPAM
IP: 2a00:1028:83a0:37a6:221:5...–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
p3can
~ Anonymní uživatel
312 příspěvků
5. 10. 2014   #11
-
0
-

#1 Martin
napis sem jak je definovana funkce
getConnection

beztak mas chybu tam.

Nahlásit jako SPAM
IP: 77.92.213.–
Martin
~ Anonymní uživatel
1602 příspěvků
5. 10. 2014   #12
-
0
-

Takže metodou pokus omyl jsem asi zjistil který to dělá příkaz, dnes už toho bylo dost, pokračování příště.

Děkuju všem za pomoc. pro p3can:

connection = new SQLiteConnection("data source=" + databaseName + ".db3");
command = new SQLiteCommand(connection);

public SQLiteConnection getConnection()
{
   return this.connection;
}
Nahlásit jako SPAM
IP: 91.187.49.–
Kit+15
Guru
5. 10. 2014   #13
-
0
-

#12 Martin
Udělej tu metodu getConnection() jako privátní. Všechny gettery a settery by měly být privátní.

Nahlásit jako SPAM
IP: 2a00:1028:83a0:37a6:221:5...–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
Kit+15
Guru
5. 10. 2014   #14
-
0
-

#12 Martin
V C# sice nedělám, ale prošel jsem si pár diskuzních fór, podle kterých by to mohlo vypadat nějak takhle: 

public void UpdateZapis(String druzstvo, String okres, bool kategorie,
        Double hodnoceniL, Double hodnoceniP, Double hodnoceni) {
    string cas = "12:00:00";
    string databaseName = "pokus";
    string connectionString = "Data Source=" + databaseName + ".db3";
    using (SQLiteConnection db = new SQLiteConnection(connectionString)) {
        db.Open();
        using (SQLiteCommand command = new SQLiteCommand(db)) {
            command.CommandText = "UPDATE TabulkaUtok SET " +
                "Lterc=@param1, Pterc=@param2, Cas=@param3, Hodnoceni=@param4 " +
                "WHERE Druzstvo=@param5 AND Okres=@param6 AND Kategorie=@param7")) {
            command.Parameters.Add(new SQLiteParameter("@param1", hodnoceniL));
            command.Parameters.Add(new SQLiteParameter("@param2", hodnoceniP));
            command.Parameters.Add(new SQLiteParameter("@param3", cas));
            command.Parameters.Add(new SQLiteParameter("@param4", hodnoceni));
            command.Parameters.Add(new SQLiteParameter("@param5", druzstvo));
            command.Parameters.Add(new SQLiteParameter("@param6", okres));
            command.Parameters.Add(new SQLiteParameter("@param7", kategorie));
            command.ExecuteNonQuery();
        }
        VypocetPoradi();
    }
}

Jenom mi není jasné, proč má ta metoda tolik parametrů, že se nevejdou na řádek a proč se parametry jmenují zrovna @param[1-7]. Neumíš je pojmenovat pořádně?

Nahlásit jako SPAM
IP: 2a00:1028:83a0:37a6:221:5...–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
p3can
~ Anonymní uživatel
312 příspěvků
6. 10. 2014   #15
-
0
-

#12 Martin

chyba bude nejspis v nektere z jinych metod, ve kterych pristupujes do db a to takova ze si neuzavrel spojeni.
#13 Kit

souvislost mezi viditelnosti a getery a setery neexistuje   
#14 Kit
mohlo by byt az na to ze nevim proc davas connectionstring jako lokalni promenou do metody.

Nahlásit jako SPAM
IP: 62.209.223.–
Kit+15
Guru
6. 10. 2014   #16
-
0
-

#15 p3can

mohlo by byt az na to ze nevim proc davas connectionstring jako lokalni promenou do metody.

Musel jsem si tu proměnnou v testu nějak nadefinovat. Normálně bych ji měl jako instanční a inicializoval v konstruktoru, to dá rozum.

Když si gettery a settery uděláš jako privátní, tak tu aplikaci musíš podle toho upravit, aby ti to fungovalo. Při těch úpravách zjistíš, že ty gettery ani settery zpravidla ani nepotřebuješ a vyhodíš je úplně. Rapidně se tím zpřehlední kód, protože se ti zúží rozhraní třídy. Instanční proměnné samozřejmě zůstanou privátní.

Nahlásit jako SPAM
IP: 2a00:1028:83a0:37a6:221:5...–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
p3can
~ Anonymní uživatel
312 příspěvků
6. 10. 2014   #17
-
0
-

#16 Kit
no nejspis proto zavedli do C# ty properties ze xD

Nahlásit jako SPAM
IP: 62.209.223.–
Kit+15
Guru
6. 10. 2014   #18
-
0
-

#17 p3can
Veřejné properties jsou zlo.

Nahlásit jako SPAM
IP: 2a00:1028:83a0:37a6:221:5...–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
p3can
~ Anonymní uživatel
312 příspěvků
6. 10. 2014   #19
-
0
-

#18 Kit
tesi me ze jsem potkal cloveka chytrejsiho nez vsichni inzenyri Microsoftu dohromady a ze sve nazory zakladas na racionalnich informacich.

Nahlásit jako SPAM
IP: 62.209.223.–
Kit+15
Guru
6. 10. 2014   #20
-
0
-

#19 p3can
Své názory zakládám na poznatcích z publikací od Roberta C. Martina a Martina Fowlera. Pro mne jsou to nejlepší znalci OOP. Znáš snad někoho lepšího?

"Inženýři z Microsoftu" jsou na můj vkus příliš anonymní a mohou vyvíjet cokoliv.

Nahlásit jako SPAM
IP: 2a00:1028:83a0:37a6:221:5...–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
p3can
~ Anonymní uživatel
312 příspěvků
6. 10. 2014   #21
-
0
-

#20 Kit
hahahaha. dobry pokus. libi se mi jak v kazdem vlakne citujes nekoho jineho. ale muzes sem napsat odkaz na material kde fowler JASNE a JEDNOZNACNE pise ze CELY system PROPERTIES v C# je spatny ?

Nahlásit jako SPAM
IP: 62.209.223.–
Kit+15
Guru
6. 10. 2014   #22
-
0
-

#21 p3can
Stačí, když se podíváš na anemický doménový model. Properties přímo svádí k použití tohoto antipatternu.

Nahlásit jako SPAM
IP: 2a00:1028:83a0:37a6:221:5...–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
p3can
~ Anonymní uživatel
312 příspěvků
6. 10. 2014   #23
-
0
-

#22 Kit
V cele problematice anemickeho domenoveho paternu nepadlo nikde ani slovo o properties to zaprve (nejspis proto ze properties PREKVAPIVE nesouvisi s adp). Si trol. V kazdem druhem vlakne brecis jak je C# naho... Uz minimalne ve 2 vlaknech se s tebou hadalo vic lidi. Kdyz napsali relevantni argumenty tak si klasicky po trolovsku prestal reagovat nebo zmenil tema. Nechapu te.

Nahlásit jako SPAM
IP: 62.209.223.–
Kit+15
Guru
6. 10. 2014   #24
-
0
-

#23 p3can
K čemu jsou tedy veřejné properties dobré? Aby se inženýři z Microsoftu mohli plácat po rameni? Zkus někoho citovat.

Nahlásit jako SPAM
IP: 37.48.35.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
p3can
~ Anonymní uživatel
312 příspěvků
6. 10. 2014   #25
-
+1
-
Zajímavé
Kit +

#24 Kit
Ja nemusim nikoho citovat. Properties nejsou nic jineho nez zkraceniny get/set, takze pokud jsou spatne properties, tak jsou spatne vsechny metody s prefixem get/set a spolu stim vsechny metody ktere plni stejnou funcionalitu, takze se ZCELA NECEKANE dostavame k tomu ze by vsechny verejne metody ktere ma objekt byly spatne.

Nahlásit jako SPAM
IP: 62.209.223.–
Martin
~ Anonymní uživatel
1602 příspěvků
6. 10. 2014   #26
-
0
-

Děkuji všem za cenné připomínky z kterých byla zjištěna chyba v této funkci. Pokud ji volám, program padá, pokud ne funguje výborně. Rovněž se chci omluvit za způsob psaní programu jak vidíte jsem jen amatér samouk. Vidí tam někdo zásadní chybu?

 public string PosledniHodnocene(bool kategorie)

{     string results = null;     getConnection().Open();     using (SQLiteCommand command2 = new SQLiteCommand("Select * FROM TabulkaUtok WHERE Kategorie = @param1  ORDER BY StartCislo ASC ", getConnection()))     {         command2.Parameters.Add(new SQLiteParameter("@param1", kategorie));

        SQLiteDataReader reader2 = command2.ExecuteReader();

        while (reader2.Read())         {             if (reader2["Hodnoceni"] + "" == "6004")             {                 results = (reader2["Druzstvo"].ToString() + " " + reader2["Okres"].ToString());                 break;             }         }     }     getConnection().Close();     return results; }

Nahlásit jako SPAM
IP: 91.187.49.–
Martin
~ Anonymní uživatel
1602 příspěvků
6. 10. 2014   #27
-
0
-

   

to samé ale snad čitelnější, předtím to vložilo nějak divně.

public string PosledniHodnocene(bool kategorie)
{
    string results = null;
    getConnection().Open();
    using (SQLiteCommand command2 = new SQLiteCommand("Select * FROM TabulkaUtok WHERE Kategorie = @param1  ORDER BY StartCislo ASC ", getConnection()))
    {
        command2.Parameters.Add(new SQLiteParameter("@param1", kategorie));

        SQLiteDataReader reader2 = command2.ExecuteReader();

        while (reader2.Read())
        {
            if (reader2["Hodnoceni"] + "" == "6004")
            {
                results = (reader2["Druzstvo"].ToString() + " " + reader2["Okres"].ToString());
                break;
            }
        }
    }
    getConnection().Close();
    return results;
}
Nahlásit jako SPAM
IP: 91.187.49.–
Kit+15
Guru
6. 10. 2014   #28
-
0
-

#27 Martin
Chybí ti tam jedno using pro otevírání databáze. Bez něho se chybně zavírá.

Nahlásit jako SPAM
IP: 2a00:1028:83a0:37a6:221:5...–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
Martin
~ Anonymní uživatel
1602 příspěvků
6. 10. 2014   #29
-
0
-

Šlo by to nějak přiblížit?

Nahlásit jako SPAM
IP: 91.187.49.–
Kit+15
Guru
Nahlásit jako SPAM
IP: 2a00:1028:83a0:37a6:221:5...–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
p3can
~ Anonymní uživatel
312 příspěvků
6. 10. 2014   #31
-
0
-

#27 Martin
reader2 musi byt v bloku using nebo volat explicitne close. to predtim ti uz funguje ?

Nahlásit jako SPAM
IP: 77.92.213.–
Martin
~ Anonymní uživatel
1602 příspěvků
7. 10. 2014   #32
-
0
-

Jestli to předtím myslíš to padání tak to bylo způsobeno právě touto funkcí, která je výše. Teď jsem ji opravil takto: 

public string PosledniHodnocene(bool kategorie)
{
    string results = null;
    getConnection().Open();
    using (SQLiteCommand command2 = new SQLiteCommand("Select * FROM TabulkaUtok WHERE Kategorie = @param1  ORDER BY StartCislo ASC ", getConnection()))
    {
        command2.Parameters.Add(new SQLiteParameter("@param1", kategorie));

        using (SQLiteDataReader reader2 = command2.ExecuteReader())
        {
            while (reader2.Read())
            {
                if (reader2["Hodnoceni"] + "" == "6004")
                {
                    results = (reader2["Druzstvo"].ToString() + " " + reader2["Okres"].ToString());
                    break;
                }
            }
        }
    }
    getConnection().Close();
    return results;
}

a vypadá to, že vše funguje dobře a bez chyb. Neseká se, neháže žádný error.

Děkuji všem za pomoc cenné rady. Jste machři

Nahlásit jako SPAM
IP: 91.187.49.–
Zjistit počet nových příspěvků

Přidej příspěvek

Toto téma je starší jak čtvrt roku – přidej svůj příspěvek jen tehdy, máš-li k tématu opravdu co říct!

Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku

×Vložení zdrojáku

×Vložení obrázku

Vložit URL obrázku Vybrat obrázek na disku
Vlož URL adresu obrázku:
Klikni a vyber obrázek z počítače:

×Vložení videa

Aktuálně jsou podporována videa ze serverů YouTube, Vimeo a Dailymotion.
×
 
Podporujeme Gravatara.
Zadej URL adresu Avatara (40 x 40 px) nebo emailovou adresu pro použití Gravatara.
Email nikam neukládáme, po získání Gravatara je zahozen.
-
Pravidla pro psaní příspěvků, používej diakritiku. ENTER pro nový odstavec, SHIFT + ENTER pro nový řádek.
Sledovat nové příspěvky (pouze pro přihlášené)
Sleduj vlákno a v případě přidání nového příspěvku o tom budeš vědět mezi prvními.
Reaguješ na příspěvek:

Uživatelé prohlížející si toto vlákno

Uživatelé on-line: 0 registrovaných, 2 hosté

Podobná vlákna

SQLite — založil Sibyx

SQLite — založil joudicek

Python a SQlite — založil ondrejruz

SQLite databáze — založil ats

 

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032024 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý