Tôi đang thực hiện một số lượng lớn INSERTS cho cơ sở dữ liệu SQLite. Tôi chỉ sử dụng một sợi. Tôi hàng loạt các bài viết để cải thiện hiệu suất và có một chút bảo mật trong trường hợp của một vụ tai nạn. Về cơ bản tôi nhớ cache một loạt dữ liệu trong bộ nhớ và sau đó khi tôi thấy thích hợp, tôi lặp lại tất cả dữ liệu đó và thực hiện INSERTS. Các mã này được hiển thị dưới đây:Tệp cơ sở dữ liệu bị khóa không thể giải thích được trong khi thực hiện SQLite cam kết
public void Commit()
{
using (SQLiteConnection conn = new SQLiteConnection(this.connString))
{
conn.Open();
using (SQLiteTransaction trans = conn.BeginTransaction())
{
using (SQLiteCommand command = conn.CreateCommand())
{
command.CommandText = "INSERT OR IGNORE INTO [MY_TABLE] (col1, col2) VALUES (?,?)";
command.Parameters.Add(this.col1Param);
command.Parameters.Add(this.col2Param);
foreach (Data o in this.dataTemp)
{
this.col1Param.Value = o.Col1Prop;
this. col2Param.Value = o.Col2Prop;
command.ExecuteNonQuery();
}
}
this.TryHandleCommit(trans);
}
conn.Close();
}
}
bây giờ tôi sử dụng các mánh lới quảng cáo sau đây để có được những điều để cuối cùng làm việc:
private void TryHandleCommit(SQLiteTransaction trans)
{
try
{
trans.Commit();
}
catch (Exception e)
{
Console.WriteLine("Trying again...");
this.TryHandleCommit(trans);
}
}
tôi tạo DB của tôi như vậy:
public DataBase(String path)
{
//build connection string
SQLiteConnectionStringBuilder connString = new SQLiteConnectionStringBuilder();
connString.DataSource = path;
connString.Version = 3;
connString.DefaultTimeout = 5;
connString.JournalMode = SQLiteJournalModeEnum.Persist;
connString.UseUTF16Encoding = true;
using (connection = new SQLiteConnection(connString.ToString()))
{
//check for existence of db
FileInfo f = new FileInfo(path);
if (!f.Exists) //build new blank db
{
SQLiteConnection.CreateFile(path);
connection.Open();
using (SQLiteTransaction trans = connection.BeginTransaction())
{
using (SQLiteCommand command = connection.CreateCommand())
{
command.CommandText = DataBase.CREATE_MATCHES;
command.ExecuteNonQuery();
command.CommandText = DataBase.CREATE_STRING_DATA;
command.ExecuteNonQuery();
//TODO add logging
}
trans.Commit();
}
connection.Close();
}
}
}
Sau đó tôi xuất chuỗi kết nối và sử dụng nó để có được các kết nối mới trong các phần khác nhau của chương trình.
Có vẻ như khoảng thời gian dường như ngẫu nhiên, mặc dù ở mức quá lớn để bỏ qua hoặc giải quyết khác vấn đề này, tôi nhận được SQLiteException unhandled: Tệp cơ sở dữ liệu bị khóa. Điều này xảy ra khi tôi cố gắng thực hiện giao dịch. Không có lỗi nào xảy ra trước đó. Điều này không luôn luôn xảy ra. Đôi khi toàn bộ điều chạy mà không có một xô.
- Không có lần đọc nào được thực hiện trên các tệp này trước khi kết thúc cam kết.
- Tôi có bản nhị phân SQLite mới nhất.
- Tôi đang biên soạn cho .NET 2.0.
- Tôi đang sử dụng VS 2008.
- db là tệp cục bộ.
- Tất cả hoạt động này được đóng gói trong một chuỗi/quy trình.
- Tính năng bảo vệ chống vi-rút bị tắt (mặc dù tôi cho rằng điều đó chỉ liên quan nếu bạn đang kết nối qua mạng?).
- Theo bài Scotsman của tôi đã thực hiện những thay đổi sau:
- Chế độ Tạp chí thiết lập để Persist
- file DB lưu trong C: \ Documents + Settings \ ApplicationData qua
System.Windows.Forms.Application.AppData
cửa sổ gọi - Không có ngoại lệ nội
- Chứng kiến trên hai máy riêng biệt (mặc dù phần cứng và phần mềm rất giống nhau)
- Đã chạy Trình theo dõi quy trình - không có quy trình không liên quan nào được gắn vào các tệp DB - vấn đề chắc chắn trong mã của tôi ...
Có ai có ý tưởng gì đang xảy ra ở đây không?
Tôi biết tôi đã bỏ toàn bộ mã lộn xộn, nhưng tôi đã cố gắng tìm ra cách này quá lâu. Lời cảm ơn của tôi đến bất cứ ai làm cho nó đến cuối câu hỏi này!
brian
CẬP NHẬT:
Cảm ơn những lời đề nghị cho đến nay! Tôi đã triển khai nhiều thay đổi được đề xuất.Tôi cảm thấy rằng chúng tôi đang tiến gần hơn đến câu trả lời ... tuy nhiên ...
Quy tắc kỹ thuật ở trên hoạt động tuy nhiên nó không xác định! Nó không được đảm bảo để làm bất cứ điều gì ngoài việc quay trong trung lập mãi mãi. Trong thực tế nó dường như làm việc ở đâu đó giữa lần lặp thứ nhất và thứ 10. Nếu tôi bó cam kết của tôi tại một khoảng thời gian hợp lý thiệt hại sẽ được giảm nhẹ nhưng tôi thực sự không muốn để lại những thứ trong trạng thái này ...
Thêm đề xuất chào mừng!
Mặc dù bạn không muốn có các cam kết nhỏ hơn - vấn đề vẫn còn xảy ra khi bạn di chuyển bắt đầu tran và cam kết tran vào vòng lặp hàng loạt bên trong? – pjp