开发者

C#: SQLite database always locked

I've written a simple app (call it app1) that reads a SQLite database and display the contents in a gridview. I have a separate C# console app (app2) that needs to write to the same database. The problem is app2 fails with a "database is locked" error. I can see as soon as I start app1 a userdb-journal file is created. I assume the problem is that app1 opens the database but doesn't release it? This is the code I have for populating the Table I bind to the grid in app1.

    public DataTable GetAllPeople()
    {
        var connectionString = "Data Source=" + dbPath + ";Version=3";

        using (SQLiteDataAdapter sqlDataAdapter =
            new SQLiteDataAdapter("SELECT id,FirstName,LastName,Address FROM Users",
                                  connectionString))
        {
            using (DataTable dataTable = new DataTable())
            {
                sqlDataAdapter.Fill(dataTable);
                // code to add some new columns here

                return dataTable;
   开发者_如何学JAVA         }
        }
    }

Here is the code that populates the gridview:

    private void Form1_Load(object sender, EventArgs e)
    {
        UserDatabase db = new UserDatabase();
        db.Initialize();
        dataGridView1.DataSource = db.GetAllPeople();

    }

How can I fix things so app2 can read and write to the database while app1 is running?

EDIT Looks like that journal file is only created by app2. I had only noticed the database locked error when app1 was running also, but perhaps app1 is a red herring. App2 is multi-threaded. Perhaps I should start a new question focusing on app2 and multithreaded access?

EDIT Thanks for all the comments. I've put a lock around all db accesses and wrapped everything up in usings. All seems to be working now.


Here is the code, set the parameters easily on the connection string builder, and build the SQLiteConnection with it.

 SQLiteConnectionStringBuilder connBuilder = new SQLiteConnectionStringBuilder();
        connBuilder.DataSource = filePath;
        connBuilder.Version = 3;
        connBuilder.CacheSize = 4000;            
        connBuilder.DefaultTimeout = 100;
        connBuilder.Password = "mypass";


        using(SQLiteConnection conn = new SQLiteConnection(connBuilder.ToString()))
        {
            //...
        }

Regards.


Have you asked SQLITE to wait and try again if the db is locked? Here's how to do it in C

 // set SQLite to wait and retry for up to 100ms if database locked
    sqlite3_busy_timeout( db, 100 );

The point is that SQLITE locks the db briefly when it is accessed. If another thread or process accesses it while blocked, SQLITE by default returns an error. But you can make it wait and try again automatically with the above call. This solves many of these kind of problems.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜