Tôi có một ứng dụng (Android 2.2 Google API Level 8) có nhiều hoạt động kéo dữ liệu từ nhà cung cấp nội dung (chỉ truy cập cơ sở dữ liệu SELECT). Nó cũng có một dịch vụ với hàng đợi nhiệm vụ chặn trung tâm chấp nhận bất kỳ tác vụ ghi cơ sở dữ liệu nào; các hoạt động có thể kích hoạt một yêu cầu dịch vụ (Theo mục đích), đặt một nhiệm vụ trên hàng đợi chặn để truy xuất tuần tự bởi một luồng và thực hiện đơn lẻ. Cơ sở dữ liệu khoảng 4mb.lỗi "sqlite" của cơ sở dữ liệu android bị khóa mặc dù sử dụng nhà cung cấp nội dung và truy cập cơ sở dữ liệu tuần tự
Có một trình trợ giúp cơ sở dữ liệu duy nhất mà dịch vụ sử dụng để gọi các phương thức tương tác với cơ sở dữ liệu bao gồm viết thư cho nó; tất cả các ghi SQL được thực hiện bên trong trình trợ giúp cơ sở dữ liệu.
- Tất cả ghi cơ sở dữ liệu đều được bao quanh bởi giao dịch.
- Tất cả các lần đọc cơ sở dữ liệu đều có con trỏ đóng ở cuối phương thức.
- Không có hoạt động nào có xử lý đối tượng cơ sở dữ liệu, chúng chỉ có thể giao tiếp thông qua nhà cung cấp nội dung hoặc dịch vụ.
- Bất kỳ tác vụ nào của AlarmManager được kích hoạt - như Hoạt động - chỉ sử dụng dịch vụ để bật tác vụ thích hợp lên hàng đợi.
- Dịch vụ là lớp duy nhất có trình điều khiển cho trình trợ giúp cơ sở dữ liệu.
- Tất cả ghi cơ sở dữ liệu chỉ được thực hiện thông qua tác vụ được đặt trên hàng đợi; Tôi đã hết sức kiểm tra việc thực hiện tác vụ đó tuần tự được nhận thức rõ ràng về nó là điều cần thiết để tránh đồng thời ghi vào cơ sở dữ liệu SQLite.
Trong khi chạy các thao tác tác vụ, tôi liên tục nhận được một hoặc hai lỗi "cơ sở dữ liệu bị khóa" khi cố ghi vào cơ sở dữ liệu được kích hoạt bởi thực hiện nhiệm vụ 'bắt đầu giao dịch'.
Khi cố gắng theo dõi nguồn khóa, tôi thấy rằng sử dụng dbhelper.inTransaction(), dbhelper.isLockedByThisThread(), dbhelper.isLockedByOtherThread() không hỗ trợ vì chúng không chỉ ra khóa cơ sở dữ liệu không mong muốn.
Những gì tôi đã tìm thấy đã làm việc trong việc phát hiện khóa sớm là tạo phương thức với beginTransaction() và setTransactionSuccessful mà không có bất kỳ mã ghi SQL thực tế nào, trong khối try try để đăng nhập vấn đề - luôn được kích hoạt bởi beginTransaction() .
Tôi đặt bẫy khóa cơ sở dữ liệu này ở bên cạnh mỗi phương thức nhiệm vụ hàng đợi chặn trong kỳ vọng/hy vọng rằng tôi sẽ tìm thấy thủ phạm đơn lẻ rời cơ sở dữ liệu ở trạng thái bị khóa sau khi hoàn tất. Tôi không thể tìm thấy một thủ phạm nhất quán. Sau khi khoan qua từ khi bắt đầu cuộc gọi đến cơ sở dữ liệu, tôi thấy rằng khóa cơ sở dữ liệu có thể xuất hiện có vẻ ngoài màu xanh mà không bị khóa bởi tác vụ trước đó (Tất cả các tác vụ này chạy theo trình tự dưới cùng một chuỗi đơn).
Sau khi xem xét một số trải nghiệm của người khác với các vấn đề về khóa cơ sở dữ liệu tôi đã cố gắng đóng kết nối cơ sở dữ liệu ngay sau khi giao dịch đã hoàn thành trên tất cả các tác vụ, nhưng điều này không giúp được gì . Đã cố gắng thêm một giấc ngủ giữa mỗi lần thực hiện nhiệm vụ; chưa được kiểm tra đầy đủ nhưng thường thấy rằng độ trễ 3 giây trở lên dường như dừng các khóa cơ sở dữ liệu xuất hiện. Đã vô hiệu hóa việc vô hiệu hoá các trình quản lý cảnh báo đã kích hoạt - không tạo ra bất kỳ sự khác biệt nào.
Hiển thị tôi có là một số hình thức nhiệm vụ bảo trì bên ngoài ứng dụng của tôi đang rơi vào và khóa cơ sở dữ liệu định kỳ - có thể trì hoãn việc ghi nhật ký.Rõ ràng là tôi ít quan tâm đến việc thiết lập một chậm trễ xử lý nhiệm vụ vì vậy tôi đang xem xét việc có một khóa cơ sở dữ liệu thử lại hàng đợi nhiệm vụ để reattempt cơ sở dữ liệu bằng văn bản khi cần thiết; nhiều người thích giải quyết nhưng đang hết ý tưởng.
Có ai có thể nghĩ ra một số nguyên tắc hoặc gotcha mà tôi đã bỏ lỡ không?
Thực tế có bình thường trong các cơ sở dữ liệu SQLite lớn hơn và Android mà bạn sẽ nhận được các khóa cơ sở dữ liệu không thường xuyên?
Cảm ơn
Có phải đọc (chọn) đến cơ sở dữ liệu được tuần tự hóa thông qua cơ chế xếp hàng hoặc có thể đọc chồng chéo với một trong các giao dịch viết của bạn không? Nếu điều này xảy ra hơn cam kết có thể thất bại. Xem chương 7 ở đây http://www.sqlite.org/lockingv3.html – Stefan