Tôi muốn truy cập cơ sở dữ liệu SQLite từ 2 luồng khác nhau, qua đó sử dụng 2 kết nối khác nhau với cơ sở dữ liệu. Cả hai chủ đề sẽ chủ yếu thực hiện đọc từ DB và sẽ chỉ viết cho DB đôi khi. Nếu tôi cảm thấy tỷ lệ cược là chống lại cả hai chủ đề bằng văn bản cho DB cùng một lúc, tôi có nên cảm thấy an toàn rằng tôi không nên có bất kỳ vấn đề nào trong trường hợp này không?Kết nối và khóa SQLite
Trả lời
SQLite là threadsafe và, với các phiên bản gần đây, bạn có thể chia sẻ một kết nối duy nhất giữa các chủ đề. Điều đó nói rằng, các câu hỏi thường gặp về SQLite "Threads Are Evil" (Tôi không nghĩ rằng chúng có nghĩa là điều này trong ngữ cảnh của SQLite, nhưng là một tuyên bố chung).
SQLite có các cơ chế khóa để ngay cả khi một cá thể thứ hai cố gắng ghi khóa trên cơ sở dữ liệu, nó sẽ được xếp hàng đợi cho tới khi các khóa hiện tại kết thúc. Câu hỏi thường gặp cho thấy thường không an toàn khi sử dụng nhiều kết nối từ các quá trình khác nhau trên hệ thống tệp mạng do khóa được triển khai kém trong hệ thống tệp, nhưng tôi không nghĩ rằng cảnh báo đó áp dụng cho việc sử dụng của bạn.
SQLite rõ ràng không phải là luồng an toàn, do đó bạn có thể mong đợi dữ liệu bị hỏng nếu bạn làm điều này.
Sử dụng khóa mutex để đảm bảo cả hai luồng không thể truy cập cơ sở dữ liệu cùng một lúc hoặc dành hàng giờ cố gắng theo dõi các lỗi tham nhũng dữ liệu ảo hiếm khi xảy ra và khó tái tạo.
Từ các tài liệu (http://www.sqlite.org/faq.html# q6): ** SQLite là luồng an toàn. ** –
Không hoàn toàn đúng. Xin vui lòng xem trả lời dài của tôi ở đây:
What are the best practices for SQLite on Android?
Bạn sẽ không tham nhũng cơ sở dữ liệu của bạn, nhưng nếu hai chủ đề khác nhau, với hai kết nối khác nhau, hãy cố gắng viết thư cho db cùng một lúc, bạn sẽ có vấn đề . Một sẽ "mất". Họ sẽ không chờ đợi để được chạy theo thứ tự. Nếu bạn gọi 'chèn' thay vì 'insertOrThrow', bạn thậm chí sẽ không nhận được ngoại lệ. Bạn sẽ không viết thư cho DB.
Đây là cách Sqlite, trong Android, hoạt động. Mỗi cá thể SqliteOpenHelper có 1 kết nối đến cơ sở dữ liệu. Nó không quan trọng bao nhiêu lần bạn gọi là 'getRead/WriteableDatabase'. Một người trợ giúp, một kết nối. Ngoài ra, mã kết nối sqlite Android thực hiện khóa luồng riêng của nó, vì vậy nếu bạn sử dụng cùng một SqliteOpenHelper, và bằng cách mở rộng, cùng một kết nối, bạn sẽ ổn.
Nếu, tuy nhiên, bạn sử dụng nhiều trình trợ giúp, bạn có thể đang gặp khó khăn.
Tôi nghi ngờ bạn có thể có nhiều chủ đề đọc, và 1 văn bản, và đi ra OK, nhưng tôi đã không thử nghiệm này.
Bạn có đang sử dụng nhiều luồng để viết hiệu suất không? Nếu vậy, tôi khuyên bạn chỉ nên tối ưu hóa việc bạn sử dụng "giao dịch". Nếu bạn làm nhiều độc lập viết, VERY của nó chậm. Nếu bạn quấn tất cả trong một lô, nó rất nhanh (tương đối). Tôi nghi ngờ điều này là bởi vì với mỗi viết độc lập, Android tuôn ra đĩa (mà là rất chậm). Nếu bạn làm chúng trong một bó, các thay đổi được thực hiện trong 1 lần viết.
Đối với việc duy trì dụ 1 helper, đây là một bài viết trên blog gần đây của tôi về nó:
http://touchlabblog.tumblr.com/post/24474750219/single-sqlite-connection
tôi đã viết một số logic tính tham khảo khá phức tạp như một phần của triển khai sớm của tôi về cảng OrmLite Android, nhưng tôi không nghĩ đó là tất cả những gì cần thiết vào thời điểm này.
http://touchlabblog.tumblr.com/post/24474455802/ormlite-for-android
Đối với đầy đủ trong các liên kết, bài viết trên blog của tôi về khóa sqlite và nhiều kết nối:
http://touchlabblog.tumblr.com/post/24474398246/android-sqlite-locking
Các liên kết đó đã chết, bạn có thể đăng những bài hiện tại, tôi thực sự muốn đọc những liên kết này hay không. Cảm ơn! – Matthias
Bạn đúng. Sẽ cần phải đào xung quanh và xem tôi có chúng không. Nếu chúng tồn tại, chúng sẽ nằm dưới http://touchlabblog.tumblr.com –
Tìm thấy chúng, cảm ơn! – Matthias
- 1. kết nối cơ sở dữ liệu sqlite/câu hỏi khóa
- 2. Kết nối chỉ đọc với ADO.NET, SQLite và TSQL
- 3. Mở kết nối Sqlite bằng khóa độc quyền trong Java/Scala bằng cách sử dụng thư viện SQlite JDBC
- 4. Không bao giờ đóng kết nối Android SQLite
- 5. Làm cách nào để kết nối Dart với SQLite?
- 6. Tôi có thể đặt kết nối sqlite và con trỏ của tôi vào một hàm không?
- 7. Kết nối với Sqlite trong android thông qua Servlet
- 8. Khóa ngoại SQLite?
- 9. Python Sqlite3 Nhận đường dẫn kết nối Sqlite
- 10. Cách tốt nhất để kết nối và sử dụng cơ sở dữ liệu sqlite từ C#
- 11. SQLite/C# Kết nối Pooling và chuẩn bị báo cáo Confusion
- 12. Kết hợp hai bảng trong SQLite
- 13. Thời gian chờ kết nối và thời gian kết nối
- 14. SQLite tương thích với khóa OpenAFS?
- 15. EF4 và Chuỗi kết nối
- 16. Lỗi khóa API trong Kết nối Facebook (javascript sdk)
- 17. Kết nối với Ổ cắm khóa giao diện người dùng
- 18. Sử dụng từ khóa IN android sqlite
- 19. Kết nối Doctrine 2 không có ràng buộc khóa ngoài
- 20. NGit tạo kết nối với một tệp khóa riêng
- 21. Kết nối Perl Kết nối
- 22. Làm cách nào để kết nối CakePHP với cơ sở dữ liệu SQLite?
- 23. Tôi làm cách nào để có thể kết nối các kết nối bằng psycopg và gevent?
- 24. Tối ưu hóa khóa ngoài trong SQLite
- 25. SQlite - Android - Cú pháp khóa ngoài
- 26. SQLite: autoincrement câu hỏi khóa chính
- 27. Cơ chế khóa rõ ràng trong SQLite
- 28. Khóa chính Sqlite trên nhiều cột
- 29. HttpURLKết nối bị khóa
- 30. Kết nối/Ghép nối tai nghe Bluetooth và Android
Cảm ơn ... Câu hỏi thường gặp là một tài nguyên tốt –
Nhưng tôi cho rằng với một kết nối sẽ không có bất kỳ yêu cầu đồng thời nào với cơ sở dữ liệu trong trường hợp @DrakeAmara. có các kết nối riêng biệt vì điều đó có nghĩa là truy cập đồng thời vào cơ sở dữ liệu – user1530779