title: flutter: Warning database has been locked for 0:00:10.000000. on Android
body: <p>I stuck at this error for a month I cannot find any solution via google.
  I build a chat app which need to work both online and offline, backend is NodeJS
  Below code is send any message that still in pending to target devices</p>
  <pre><code>  async function _worker(socket) {
      console.log('worker running...')
      await connect.then(async (db) =&gt; {
  
          // When user A sent message to user B but user B is offline so server need to sync this message to user B
          Message.find({ isDeliver: 0 }).then(async (m) =&gt; {
              if (m.length &gt; 0) {
                  for (let i = 0; i &lt; m.length; i++) {
                      let sender = m[i].sender;
                      let receiver = m[i].receiver;
                      let online = await checkUserOnline(socket, receiver);
                      if (online) {
                          let to_user_socket_id = getSocketIDfromMapForthisUser(`${receiver}`)
                          sendToConnectedSocket(socket, to_user_socket_id, &quot;send_message_to_device&quot;, m[i]);
                      }
                  }
              }
          });
  
           // When user A sent a message to user B and user B is offline but when user B is online and message delivered to user B and user A is offline server need to sync this message status to update for user A
           Message.find({ isDeliver: 1 }).then(async (m) =&gt; {
              if (m.length &gt; 0) {
                  for (let i = 0; i &lt; m.length; i++) {
                      let sender = m[i].sender;
                      let receiver = m[i].receiver;
                      let online = await checkUserOnline(socket, sender);
                      if (online) {
                          let to_user_socket_id = getSocketIDfromMapForthisUser(`${sender}`)
                          sendToConnectedSocket(socket, to_user_socket_id, &quot;send_message_deliver&quot;, m[i]);
                      }
                  }
              }
          });
  
          // When user A sent a message to user B and user B is offline but when user B is online and read the message and user A is offline server need to sync this message status to update for user A
          Message.find({ isRead: 1 }).then(async (m) =&gt; {
              if (m.length &gt; 0) {
                  for (let i = 0; i &lt; m.length; i++) {
                      let sender = m[i].sender;
                      let receiver = m[i].receiver;
                      let online = await checkUserOnline(socket, sender);
                      if (online) {
                          let to_user_socket_id = getSocketIDfromMapForthisUser(`${sender}`)
                          sendToConnectedSocket(socket, to_user_socket_id, &quot;send_message_read&quot;, m[i]);
                      }
                  }
              }
          });
  
      });
   }
  </code></pre>
  <p>and below is a method to handle event from server:</p>
  <blockquote>
  <p>Socket</p>
  </blockquote>
  <pre><code>setOnServerSendDeliver(Function  onServerSendDeliver) {
      _socket.on('send_message_deliver', (data) {
          onServerSendDeliver(data);
      });
    }
  
    setOnServerSendRead(Function  onServerSendRead) {
      _socket.on('send_message_read', (data) {
        onServerSendRead(data);
      });
    }
  
    setOnServerSendToDevice(Function onServerSendToDevice) {
      _socket.on('send_message_to_device', (data) {
        onServerSendToDevice(data);
      });
    }
  </code></pre>
  <blockquote>
  <p>Method</p>
  </blockquote>
  <pre><code> onServerSendDeliver(data) async {
      MessageModel message = MessageModel.fromJson(jsonDecode(data));
      await G.dbService.updateDeliver(message);
      G.socketUtils.sendDeliveryDone(message, new UserModel(id: message.sender));
      refreshMessage();
    }
  
    onServerSendRead(data) async {
      MessageModel message = MessageModel.fromJson(jsonDecode(data));
      await G.dbService.updateRead(message.chatId);
      G.socketUtils.sendReadDone(message, new UserModel(id: message.sender));
      refreshMessage();
    }
  
    onServerSendToDevice(data) async {
      MessageModel message = MessageModel.fromJson(jsonDecode(data));
      ChatModel chat = new ChatModel();
      chat.id = message.chatId;
      chat.fromId = message.sender;
      chat.toId = message.receiver;
      chat.message = message.content;
      await G.dbService.chatOperation(chat);
      await G.dbService.insertMessage(message);
      await G.dbService.updateDeliver(message);
      G.socketUtils.sendDelivery(message, new UserModel(id: message.sender));
      refreshMessage();
    } 
  </code></pre>
  <p>in server I set</p>
  <p><code>setInterval(_worker, 1500, socket);</code></p>
  <p>to load check message and send to end devices</p>
  <p>and my database function</p>
  <pre><code>Future&lt;String&gt; updateRead(String chatId) async {
      Database db = await database;
      try {
        await db.transaction((txn) async {
          return await txn.rawUpdate(
              &quot;UPDATE messages SET isRead = 1, isSend = 1, isDeliver = 1 WHERE chatId = ? AND status = 0&quot;,
              [chatId]);
        });
  
        await db.transaction((txn) async {
          return await txn.rawUpdate(
              &quot;UPDATE chats SET isRead = 1, isSend = 1, isDeliver = 1 WHERE id = ? AND status = 0&quot;,
              [chatId]);
        });
      } catch (e) {
        print(e.toString());
      }
      return chatId;
    }
  
    Future&lt;String&gt; updateDeliver(MessageModel message) async {
      Database db = await database;
      String id;
      try {
        id = message.id;
        await db.transaction((txn) async {
          return await txn.rawUpdate(
              &quot;UPDATE messages SET isDeliver = 1 WHERE id = ? AND status = 0&quot;,
              [message.id]);
        });
  
        await db.transaction((txn) async {
          return await txn.rawUpdate(
              &quot;UPDATE chats SET isDeliver = 1 WHERE id = ? AND status = 0&quot;,
              [message.chatId]);
        });
      } catch (e) {
        print(e.toString());
      }
      return id;
    } 
  </code></pre>
  <p>iOS is working fine but on android I always got this error and my app stuck:</p>
  <blockquote>
  <p>flutter: Warning database has been locked for 0:00:10.000000. Make sure you always use the transaction object for database operations during a transaction</p>
  </blockquote>
  <p>Any help would be appropriate</p>
  <p><strong>Update</strong></p>
  <p>I tried to modify the database function to:</p>
  <pre><code>Future&lt;String&gt; updateDeliver(MessageModel message) async {
      Database db = await database;
      String id;
      try {
        id = message.id;
        await db.transaction((txn) async {
          var batch = txn.batch();
          batch.rawUpdate(
              &quot;UPDATE messages SET isDeliver = 1 WHERE id = ? AND status = 0&quot;,
              [message.id]);
          batch.rawUpdate(
              &quot;UPDATE chats SET isDeliver = 1 WHERE id = ? AND status = 0&quot;,
              [message.chatId]);
          batch.commit();
        });
      } catch (e) {
        print(e.toString());
      }
      return id;
    }
  </code></pre>
  <p>but I still faced the same issue</p>