2015-04-22 16 views
6

Trong ứng dụng MVVMCross trên Android và iOS của chúng tôi, chúng tôi thỉnh thoảng gặp phải SQLiteException: các ngoại lệ bận.SqliteException bận rộn iOS/Android Xamarin MVVMCross

Với mã bên dưới, chúng tôi có một số kho lưu trữ trong đó xây dựng một thể hiện của bên dưới và kết nối liên quan đến cơ sở dữ liệu Sqlite. Hãy tưởng tượng chúng ta có Stock Stock Repository và Valository Repository, hai trường hợp của SqliteDataService sẽ được tạo: SqliteDataService với kiểu Stocks và SqliteDataService với kiểu Valuations, mỗi loại có một kết nối tới cơ sở dữ liệu Sqlite.

Hành động trên các kho lưu trữ có thể hoạt động trên các chủ đề nền có nghĩa là chúng tôi có thể cố gắng chèn Cổ phiếu vào cơ sở dữ liệu cùng lúc với Định giá.

Bây giờ, mỗi kho lưu trữ tạo SqliteDataService riêng của mình khóa connectionObject sẽ chỉ bảo vệ cùng một kiểu kho lưu trữ truy cập cơ sở dữ liệu cùng một lúc thay vì bảo vệ Cổ phiếu và Định giá truy cập cơ sở dữ liệu cùng một lúc.

Câu hỏi của tôi là:

Có hiệu lực để tạo ra một kết nối cho mỗi kho và nếu như vậy, làm thế nào để chúng ta bảo vệ chống lại SqliteException: bận rộn?

Có mô hình nào tốt hơn không? tức là chúng ta có nên tạo một lớp SqliteDataService không chung chung có cùng kết nối với các luồng không? Chúng tôi đã thử điều này nhưng trên Android, chúng tôi gặp phải các ngoại lệ gây tử vong.

Có ai có mẫu Sqlite DAL vững chắc cho Xamarin MVVMCross không?

public class SqliteDataService<T> : IDataService<T> where T : new() 
{ 
    private static object lockObject = new object(); 

    private static object connectionObject = new object(); 

    private static ISQLiteConnection _connection; 

    private static SqliteDataService<T> _instance; 

    public SqliteDataService(ISQLiteConnectionFactory connectionFactory, string dbPath) 
    { 
     if (_connection == null) 
     { 
      _connection = connectionFactory.Create (dbPath); 
      _connection.CreateTable<T>(); 
     } 
    } 

    public static SqliteDataService<T> GetInstance(ISQLiteConnectionFactory connectionFactory, string dbPath) 
    { 

     if (_instance == null) 
     { 
      lock (lockObject) 
      { 
       _instance = new SqliteDataService<T> (connectionFactory, dbPath); 
      } 
     } 

     return _instance; 
    } 

    public void CreateTable<T>() 
    { 

    } 

    public void Insert(T value) 
    { 
     lock (connectionObject) { 
      _connection.Insert (value, typeof(T)); 
     } 
    } 

    public void InsertAll(IEnumerable<T> values) 
    { 
     lock (connectionObject) { 
      _connection.Insert (values, typeof(T)); 
     } 
    } 

    public IEnumerable<T> Read(Expression<Func<T, bool>> predicate) 
    { 
     lock (connectionObject) { 
      return _connection.Table<T>().Where (predicate); 
     } 
    } 

    public T ReadFirst(Expression<Func<T, bool>> predicate) 
    { 
     lock (connectionObject) { 
      return Read (predicate).FirstOrDefault(); 
     } 
    } 

    public void Update(T value) 
    { 
     lock (connectionObject) { 
      _connection.Update (value, typeof(T)); 
     } 
    } 

    public void Delete(Expression<Func<T, bool>> predicate) 
    { 
     lock (connectionObject) { 
      var valuesToDelete = Read (predicate); 

      if (valuesToDelete == null) 
       return; 

      foreach (var value in valuesToDelete) { 
       _connection.Delete (value); 
      } 
     } 
+0

Bạn đã sửa lỗi này? Vui lòng đăng câu trả lời nếu câu trả lời được sửa. –

Trả lời

0

Nghe có vẻ như bạn có một vài lựa chọn:

  1. nhanh chóng chỉ một SqliteDataService duy nhất và vượt qua một tham chiếu đến nó để cả cổ phiếu của mình và các đối tượng Định giá, điều này có vẻ hợp lý nhất là cả hai đều hoạt động trên cùng một DB

  2. Khởi tạo đối tượng để sử dụng như khóa bên ngoài dịch vụ và chuyển tham chiếu vào hàm tạo SqliteDataService để khóa được chia sẻ bởi cả hai dịch vụ. Tôi tin rằng điều này sẽ làm việc nhưng tôi không có chuyên gia về khóa.

  3. Bạn có thể xử lý ngoại lệ bận trong khối thử và lặp lại bộ đếm để thực hiện số lần thử tối đa đối với cơ sở dữ liệu với thời gian chờ đợi ngắn để bạn có cơ hội kết nối tốt. Nếu DB vẫn bận, bạn vẫn sẽ nhận được ngoại lệ và giải pháp này khá là lộn xộn.

  4. Tái cơ cấu DB sao cho hai khu vực được tách ra, điều này có thể là không thể nhưng đáng để suy nghĩ.

Các vấn đề liên quan