1

I'm working on a App that have more than 50 tables and can work without internet connection, so in background the app can sync up with the API and get all the information and make the CRUD operation in local.

Sometimes when the app is sync up with the API, I'm getting the error "Database is LOCKED", when I'm making another operation on the App.

So I need help to solve this, I know that there are a lot of post about this problem, but base on my implamentation with my database, it seems not to be enough to solve my problem.

Nugets: Xamarin.Forms 3.0.0 482510 sqlite-net-pcl 1.5.166-beta

I use a class DataService.cs where that class connect with the DataContext.cs and make the connection with database and methods CRUD. All methods in the DataService have the same way to connect with DataContext:

    //This is a resume of DataService.cs
        public class DataService 
            {
                public T Insert<T>(T model)
                {
                    try
                    {
                        using (var da = new DataContext())
                        {
                            da.Insert(model);
                            return model;
                        }
                    }
                    catch (Exception error)
                    {
                        error.ToString();
                        return model;
                    }
                }
        }

In DataContext.cs we have the connection with the local database and all the methods with the local database . All methods have the collisionLock (to avoid conflict with database) and cnn.Dispose() (To close connection with the database and avoid the error Fatal signal 11 (SIGSEGV));

DataContext.cs

    public interface IBusinessEntity
        {
            int ID { get; set; }
        }


         //This is a resume of DataContext.cs
            public class DataContext : IDisposable
            {
                #region Attributes
                public SQLiteConnection cnn;
                private static object collisionLock = new object();
                #endregion


                public DataContext()
                {
                    cnn = DependencyService.Get<IConfiguracion>().GetConnection();
        ...
        } 
                #endregion

                #region MetodosGenericosZulu
                public void Insert<T>(T model)
                {
                    try
                    {
                        // Use locks to avoid database collisions
                        lock (collisionLock)
                        {
                            cnn.Insert(model);
                            cnn.Dispose();
                        }
                    }
                    catch (Exception error)
                    {
                        Application.Current.MainPage.DisplayAlert(
                            "Error",
                            "Un error a ocurrido con la DB (Insert): " + error.Message.ToString(),
                            "Ok");
                    }
                }

                public void Update<T>(T model)
                {
                    try
                    {
                        lock (collisionLock)
                        {
                            cnn.Update(model);
                            cnn.Dispose();
                        }
                    }
                    catch (Exception error)
                    {
                        Application.Current.MainPage.DisplayAlert(
                                            "Error",
                                            "Un error a ocurrido con la DB (Actualizar): " + error.Message.ToString(),
                                            "Ok");
                    }
                }

                ...
        }
        }

Implentation on Android project.

    public class Configuracion : IConfiguracion
        {
            public Configuracion(){ }

            public SQLite.SQLiteConnection GetConnection()
            {
                    var sqliteFileName = "FN_Desarrollo.db3";
                    string documentsPath = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal);
                    var path = Path.Combine(documentsPath, sqliteFileName);
                  var  conn = new SQLite.SQLiteConnection(path, SQLiteOpenFlags.ReadWrite | SQLiteOpenFlags.Create | SQLiteOpenFlags.SharedCache);

                return conn;
            }
        }

So I need your help guys to solve the problem (database locked) and review if my implementation with the SQLite is OK.

I'm hearing all the suggestions.

Thanks in advance.

  • **Database is locked** means that you open your database and don't close after use. And when you open it again, you receive this sort of exception. Analyze your code and be sure that you close connections after every use of it. – Денис Чорный Jun 10 '19 at 02:35
  • Thanks for you answer. I'm using cnn.Dispose () in all my DB methods to close the connection, but let me check it again to see if I'm loosing one of them. But really I think that all the time I'm going to receive that exception beacause my App can run the sync up every 5 minutes in background and on the main UI we can do another operation with the local DB. – Eleazar Saavedra Jun 10 '19 at 14:00
  • 1
    check this answer: https://stackoverflow.com/questions/17168839/what-is-the-difference-between-connection-close-and-connection-dispose Probably, there is a place in your code, where connection not closing properly. Try to use `using (...)` with brackets. – Денис Чорный Jun 11 '19 at 06:21
  • Thanks Денис Чорный, I going to check that. – Eleazar Saavedra Jun 11 '19 at 12:57

1 Answers1

0

I finished using one connection for all operations with the local DB.

On the Sqlite Documentation, they recommend open the connection once and never close it.

public class DataContext
    {
        public static SQLiteConnection cnn;

        public DataContext()
        {
            if (cnn == null)
            {
               Create your tables.
               cnn.CreateTable<...>();
               ...
            }
        }
   }