SQLite với hai quá trình python truy cập vào nó: một đọc, một viết


22

Tôi đang phát triển một hệ thống nhỏ với hai thành phần: một cuộc thăm dò dữ liệu từ tài nguyên internet và chuyển nó thành dữ liệu sql để duy trì cục bộ; người thứ hai đọc dữ liệu sql đó từ cá thể cục bộ và phục vụ nó thông qua json và một api yên tĩnh.

Ban đầu tôi dự định duy trì dữ liệu bằng postgresql, nhưng vì ứng dụng sẽ có khối lượng dữ liệu rất thấp để lưu trữ và lưu lượng để phục vụ, tôi nghĩ rằng điều đó là quá mức cần thiết. SQLite có phù hợp với công việc không? Tôi thích ý tưởng về dấu chân nhỏ và không cần phải duy trì một máy chủ sql khác cho một nhiệm vụ này, nhưng lo ngại về sự tương tranh.

Có vẻ như với tính năng ghi nhật ký trước được kích hoạt, việc đọc và ghi cơ sở dữ liệu SQLite có thể xảy ra mà không cần khóa quá trình ra khỏi cơ sở dữ liệu.

Một cá thể SQLite duy nhất có thể duy trì hai quá trình đồng thời truy cập vào nó không, nếu chỉ một lần đọc và một lần khác ghi? Tôi bắt đầu viết mã nhưng tự hỏi liệu đây có phải là ứng dụng sai của SQLite không.


3
@gnat Mát mẻ. Một cá thể SQLite duy nhất có thể duy trì hai quá trình đồng thời truy cập vào nó không, nếu chỉ một lần đọc và một lần khác ghi? Tôi bắt đầu viết mã nhưng tự hỏi liệu đây có phải là ứng dụng sai của SQLite không.
bb

Chỉ cần một cái đầu lên. Trong công ty trước đây của chúng tôi, chúng tôi đã sử dụng SQL (cả MS và Oracle Express) cho một số lưu trữ và chúng tôi luôn cảm thấy rằng với những gì chúng tôi lưu trữ, chúng tôi không cần DB đầy đủ. Vì vậy, trong một trong những bản phát hành, chúng tôi quyết định làm chính xác những gì bạn đang làm. Thay thế các sản phẩm đó bằng SQLite. Chúng tôi đã có chính xác điều tương tự, một nhà văn sẽ đặt dữ liệu trên đĩa và cập nhật quy trình đọc và TOC dựa trên SQL (nhiều luồng) sẽ đọc TOC để xác định dữ liệu nào cần truy xuất. Không biết về SQLite những ngày này, nhưng những gì chúng ta gặp phải đồng thời hóa ra lại là một nỗi đau lớn trong ...
DXM

... Phía sau. Tôi không nhớ tất cả các chi tiết, nhưng tôi nghĩ khi một quá trình cố gắng để có được một khóa và không thể bởi vì một người khác đang đọc, nó sẽ SLEEP cho một cái gì đó điên rồ như 20-30 giây. Cuối cùng chúng tôi đã tạo ra một luồng chuyên dụng chịu trách nhiệm truy cập SQLite và sau đó chúng tôi có cả các quy trình của chúng tôi và tất cả các luồng trong chúng, tuần tự hóa các yêu cầu DB của chúng đến một luồng đó. Nhìn nhận lại, có lẽ tôi sẽ không đi với SQLite nữa.
DXM

1
@DXM cảm ơn vì đã cảnh báo, nhưng sau khi chạy một vài bài kiểm tra, tôi đã không chạy đua với bất cứ điều gì tương tự. Tôi biết sqlite đã có một cuộc đại tu lớn với phiên bản 3, vào khoảng năm 2004, vì vậy tôi tự hỏi liệu trải nghiệm tiêu cực của bạn có từ trước thời điểm đó không.
bb

1
... Chính bạn, thay vì dựa vào các sơ đồ khóa của SQLite. Tôi đã không tự mình làm công việc đó, đó là một đội khác nhưng tôi giữ trong vòng lặp chủ yếu là để cung cấp phản hồi và vì tò mò. Tôi cũng đã lên mạng và đọc một số độc lập và tìm thấy trang của tác giả gốc. Từ việc đọc nó, tôi có ấn tượng rằng người phát minh ra SQLite chỉ ghét các chủ đề và không hiểu tại sao mọi người sẽ sử dụng chúng, vì vậy a) DB không được thiết kế với chúng trong tâm trí và b) khóa / bảo vệ được thêm vào / hack vào như một suy nghĩ lại vì quá nhiều người yêu cầu nó.
DXM

Câu trả lời:


25

Bạn đang tìm tài liệu Khóa và Đồng thời .

Các quy trình SQLite sử dụng một loạt các khóa để xử lý đồng thời; để đọc, một số quy trình có thể có được một SHAREDkhóa.

Một quá trình ghi, sẽ cần phải có được một RESERVEDkhóa, và chỉ khi thực sự phải xóa các thay đổi vào đĩa thì nó mới chuyển sang PENDINGtrạng thái. Bất kỳ quá trình đọc nào sau đó sẽ phải mở khóa tệp, sau đó quá trình viết có thể chuyển sang EXCLUSIVEđể ghi vào tệp cơ sở dữ liệu thực tế.

Bởi vì quá trình nhà văn chỉ cần khóa tệp cơ sở dữ liệu để ghi thực tế (xóa bộ nhớ, cam kết), một thiết lập chỉ với một người đọc và chỉ một nhà văn sẽ thực hiện khá tốt. Tôi hy vọng nó sẽ hoạt động tốt, nếu không tốt hơn, như một thiết lập chỉ với một quá trình thực hiện tất cả việc đọc và viết.

SQLite ít phù hợp hơn khi bạn có nhiều quy trình thường xuyên ghi vào cùng một cơ sở dữ liệu, vì việc viết đòi hỏi phải có PENDINGkhóa độc quyền để tuần tự hóa các thay đổi.


Cảm ơn câu trả lời thấu đáo Martijn! Tôi có một số tập lệnh để thực hiện một số thử nghiệm và có vẻ như hai quá trình sẽ vui vẻ đọc và viết một ví dụ sqlite duy nhất đồng thời. Tôi đã thực hiện đồng thời đọc và viết các yêu cầu bắn ra cứ sau 1/100 giây và vẫn không nhận được ngoại lệ db bị khóa. Thật kỳ lạ, lần duy nhất tôi nhận được thông báo lỗi "khóa cơ sở dữ liệu" là khi thử thủ công (với ứng dụng khách dòng lệnh sqlite3) để xóa một vài hàng trong khi các yêu cầu đọc được kích hoạt từ tập lệnh của tôi ở tốc độ 1/100 giây. Tôi tự hỏi nếu pysql tự động thử lại một ghi sau một lỗi như vậy.
bb

10

Chỉ muốn theo dõi và cho mọi người biết rằng việc thực hiện đã thành công. Làm việc với SQLite là một niềm vui thực sự và chỉ với một quá trình viết nó tại một thời điểm chúng tôi không bao giờ gặp vấn đề với việc khóa ... ngay cả với các lần đọc đồng thời rất nhanh từ một quy trình thứ cấp.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.