База данных sqflite блокируется флаттер - База данных предупреждений заблокирована

Я использую SQLite в своем проекте flutter и пытаюсь выяснить проблему блокировки БД, в моем сценарии пользователь пытается загружать новые данные один раз в день, и если эта запись существует, она обновится или вставит новую запись. Моя проблема в том, что хотя я использую транзакцию и пакет, я получаю ошибку блокировки БД, единственная проблема, о которой я могу думать, - это вызов getSongList (), поскольку он вызывает БД из этой транзакции или пакета несколько раз, но этот вызов чтения, и мой код кажется сбой во время пакетной фиксации.

buildDB1(List<MusicData> _list, int version) async {
    await openDb();
    try {
      _database.transaction((txn) async {
        Batch batch = txn.batch();
        for (var i = 0; i < _list.length; i++) {
          // buildBatch(_list[i]);
          MusicData musicData = _list[i];
          int id = musicData.id;
          if (musicData.pdfpage == 0 || musicData.pdfpage == null) {
            PDFPAGE = "0";
          } else {
            PDFPAGE = (musicData.pdfpage).toString();
          }
          if (musicData.linkid == 0 || musicData.linkid == null) {
            LINKID = "0";
          } else {
            LINKID = (musicData.linkid).toString();
          }
          // PDFPAGE = musicData.pdfpage as String;
          // LINKID = musicData.linkid as String;
          TITLE = musicData.title;
          ALBUM = musicData.album;
          SONGURL = musicData.songURL;
          HINDINAME = musicData.hindiName;
          MNAME = musicData.mname;
          MSIGN = musicData.msign;
          OTHER1 = musicData.other1;
          OTHER2 = musicData.other2;
          ENAME = musicData.ename;
          ESIGN = musicData.esign;
          LANGUAGE = musicData.language;
          SONGTEXT = musicData.songtext;
          Future<List<MusicData>> list1 =
              getSongList("select * from songs where id=$id");
          List<MusicData> list = await list1;
          if (list.length != 0) {
            String updateSQL =
                "UPDATE SONGS SET pdfpage = $PDFPAGE, linkid = $LINKID, title = '$TITLE', album = '$ALBUM', songURL = '$SONGURL', hindiName = '$HINDINAME', mname = '$MNAME', msign = '$MSIGN', other1 = '$OTHER1', other2 = '$OTHER2', ename = '$ENAME', esign = '$ESIGN', language = '$LANGUAGE',songtext = '$SONGTEXT' WHERE id = $ID";
            batch.rawUpdate(updateSQL);
            // _database.rawUpdate(
            //     "UPDATE SONGS SET pdfpage = ?, linkid = ?, title = ?, album = ?, songURL = ?, hindiName = ?, mname = ?, msign = ?, other1 = ?, other2 = ?, ename = ?, esign = ?, language = ?,songtext = ? WHERE id = ?",
            //     [
            //       musicData.id,
            //       musicData.pdfpage,
            //       musicData.linkid,
            //       musicData.title,
            //       musicData.album,
            //       musicData.songURL,
            //       musicData.hindiName,
            //       musicData.mname,
            //       musicData.msign,
            //       musicData.other1,
            //       musicData.other2,
            //       musicData.ename,
            //       musicData.esign,
            //       musicData.language,
            //       musicData.songtext
            //     ]);

            print("Record updated in db $id");
            // _database.close();
          } else {
            String insertSQL =
                "INSERT INTO SONGS (pdfpage, linkid, title,album,songURL,hindiName,mname,msign,other1,other2,ename,esign,language,songtext,isfav) VALUES ($PDFPAGE,$LINKID,'$TITLE','$ALBUM','$SONGURL','$HINDINAME','$MNAME','$MSIGN', '$OTHER1','$OTHER2','$ENAME','$ESIGN','$LANGUAGE','$SONGTEXT',0)";
            batch.rawInsert(insertSQL);
            // _database.insert('SONGS', musicData.toMap());
            print("Record inserted in db $id");
          }
        }
        Future<List> result = batch.commit();
      });
      SharedPreferences prefs = await SharedPreferences.getInstance();
      await prefs.setInt('dbversion', version);
    } catch (e) {
      print(e);
    }
  }

person Akshay    schedule 08.06.2020    source источник


Ответы (1)


getSongList должен принимать аргумент транзакции. Обычно используйте txn вместо _database в любых вызовах db во время транзакции. В противном случае он зависнет, и предупреждение будет правильным.

Также вы можете попасть в какое-то состояние гонки, так как вы не ждете batch.commit до окончания транзакции. Вы можете попробовать заменить:

Future<List> result = batch.commit();

by

await batch.commit();

Использование pedantic может предупредить вас об отсутствии здесь await.

person alextk    schedule 08.06.2020
comment
Я уже пробовал оба этих варианта, и это не помогло. - person Akshay; 08.06.2020
comment
@ Акшай, ты нашел решение? - person S. Aziz Kazdal; 14.11.2020
comment
@ S.AzizKazdal да, я нашел решение, но я обработал это в своем коде, чтобы избежать пакетной загрузки. - person Akshay; 18.11.2020