2017-04-13 7 views
2

Sqlite.swiftエラーを投げている:挿入するためにトランザクションを使用すると、私はそうとDatabaseクラスを作成している

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 
     } 
} 

私は、次を実行して、行を追加するために私のコードを呼び出すために行く:

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

挿入し、操作を完了できませんでしたが失敗しました:

私が持っている問題は、それが常に言ってエラーをスローということです。 (SQLite.Result エラー0)とフル: - :私はこのエラーに私のMacは窓の外に行くことになる1つの以上の時間が表示された場合

ロールバックすることはできません何のトランザクションがアクティブ( 1コード)です!

全体の動作は、バックグラウンドスレッドであるが、私は同様に、次の試してみました:

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

それは動作しませんでした。トランザクションでテーブルを作成しようとしたが、それは完全に機能していたので意味がありません。

ご協力いただければ幸いです!

+0

これを遊び場で実行するとどうなりますか? – rmon2852

+0

私はこれがスレッドの問題であると考え始めています。私はこれをコードの残りの部分と分離して動作させることができます。今私が述べていないことの1つは、コードがAlamofire完了ブロックから実行されるということです。 –

答えて

0

func createTable()func addRow()メソッドはスレッドセーフではありません。複数のスレッドが同時にアクセスできます。

シングルトンクラス内にプライベートシリアルDispatchQueueを作成し、このシリアルキューを介して上記の機能を実行します。これにより、同時に複数のスレッドからデータベースにアクセスできなくなり、シリアルキューは並行タスクをキューに入れます。

+0

はい、または難しいスレッド処理を行うSQLiteライブラリを使用してください:https://github.com/groue/ GRDB.swift/blob/master/README.md#concurrency –

+0

しかし、私はリチャードがスレッディング問題を抱えているとは思わない。 –

関連する問題