ブログ

割とコンピュータよりの情報をお届けします。

2019年3月10日

SQLiteのデータベースファイルへの同時アクセス

SQLiteでは複数のプロセスからの同時アクセスはできないというページをよく見るが,一応参照は問題ないということらしい.

SQLiteを使ってデータを書き込んでみた.そのデータを参照するプロセスは複数でもよいらしい.
実際にSQLiteでデータベースを使うアプリを作ってみるとそのようだ.
実際には,Windowsの場合にはあまりお勧めしないが,一応同時アクセスを可決しようとしている実装になっているらしい.
ただし,あらゆる環境で確実な動作を保証していなそうな記述がみられる.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

using System.Data.SQLite;

namespace SQLiteSample
{
    public partial class Form1 : Form
    {
        private System.Data.SQLite.SQLiteConnection cn;

        public Form1()
        {
            InitializeComponent();

            SQLiteConnectionStringBuilder sqlConnectionSb = new SQLiteConnectionStringBuilder { DataSource = "test.db" };
            this.cn = new SQLiteConnection(sqlConnectionSb.ToString());
            this.cn.Open();

            var cmd = new SQLiteCommand(cn);
            cmd.CommandText = "CREATE TABLE IF NOT EXISTS test(" +
                    "datetime INTEGER NOT NULL PRIMARY KEY," +
                    "value REAL)";
            cmd.ExecuteNonQuery();
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            this.cn.Close();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            Int64 datetime = DateTime.Now.Ticks;
            Double value = datetime;
            var cmd = new SQLiteCommand(cn);
            cmd.CommandText = "INSERT INTO test(datetime, value) "
                               + "VALUES("
                               + $"{datetime}, {value})";
            cmd.ExecuteNonQuery();
        }
    }
}

クライアント側

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Data.SQLite;

namespace SQLView
{
    public partial class Form1 : Form
    {
        private System.Data.SQLite.SQLiteConnection cn;
        private DataSet ds;
        private System.Data.SQLite.SQLiteDataAdapter da;

        public Form1()
        {
            InitializeComponent();

            SQLiteConnectionStringBuilder sqlConnectionSb = new SQLiteConnectionStringBuilder { DataSource = "../../../SQLiteSample/bin/Debug/test.db" };
            this.cn = new SQLiteConnection(sqlConnectionSb.ToString());
            this.cn.Open();

            ds = new DataSet();
            da = new SQLiteDataAdapter();
            var cmd = new SQLiteCommand(cn);
            cmd.CommandText = "SELECT * FROM test ORDER BY datetime asc";
            da.SelectCommand = cmd;

            da.Fill(ds, "test");
            this.dataGridView1.DataSource = ds.Tables["test"];
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            this.cn.Close();
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            if (ds.Tables["test"].Rows.Count > 0)
            {
                Int64 last = (Int64)ds.Tables["test"].Rows[ds.Tables["test"].Rows.Count - 1][0];
                var cmd = new SQLiteCommand(cn);
                cmd.CommandText = "SELECT * FROM test WHERE datetime > "
                    + $"{last}" 
                    + " ORDER BY datetime asc";
                da.SelectCommand = cmd;
            }

            this.da.Fill(ds, "test");
        }
    }
}

≫ 続きを読む

2019/03/10 コンピュータ   TakeMe