Using transactions to insert is throwing errors Sqlite.swift

雨燕双飞 提交于 2019-12-08 02:15:00

问题


I have created a Database class as so:

class Database {
    static let instance = Database()
    private let categories = Table("Category")
    private var db: Connection?

    let cat_id = Expression<String>("id")
    let cat_name = Expression<String>("name")


    private init() {
        let path = NSSearchPathForDirectoriesInDomains(
            .documentDirectory, .userDomainMask, true
            ).first!
        do {
            db = try Connection("\(path)/SalesPresenterDatabase.sqlite3")
            createTable()
        } catch {
            print("error")
        }
    }
    func createTable() {
        do{
            try self.db!.run(self.categories.create(ifNotExists: true) { table in
                table.column(self.cat_id)
                table.column(self.cat_name)
            })
        }catch{
             print("error")
        }
    }

    func addRow(table: DBTableNames, object: [Any]) -> Int64? {
      do {
         try self.db!.transaction() {
            for obj in object{
                if table.rawValue == DBTableNames.Category.rawValue{
                    let cats : CategoryObject = obj as! CategoryObject
                    let insert = self.categories.insert(self.cat_id <- cats.id,
                                                        self.cat_name <- cats.name)
                    try self.db!.run(insert)

                }
             }
          }
        }catch{
           print("Insert failed \(error)")
           return -1
        }
        return 1
         }
}

I then go on to call my code to add a row by running the following:

    let returnValue = Database.instance.addRow(table: DBTableNames(rawValue: entity)!,
                                               object: databaseObject)

The problem I have is that it always throws an error saying:

Insert failed The operation couldn’t be completed. (SQLite.Result error 0.) and full: cannot rollback - no transaction is active (code: 1)

If I see this error one more time my Mac will be going out of the window!

The whole operation is in a background thread but I have tried the following as well:

    DispatchQueue.main.async{
    let returnValue = Database.instance.addRow(table: DBTableNames(rawValue: entity)!,
                                                   object: databaseObject)
}

It didn't work. It doesn't make sense as I also tried creating the tables in a transaction and that worked perfectly.

Any help would be greatly appreciated!


回答1:


Your func createTable() and func addRow() methods are not thread safe. Multiple threads can access it at the same time.

Create a private serial DispatchQueue inside your Singleton class and do above functions through this serial queue. This will prevent accessing the database from several threads at the same time, and serial queue will queue concurrent tasks.



来源:https://stackoverflow.com/questions/43388443/using-transactions-to-insert-is-throwing-errors-sqlite-swift

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!