Search code examples
react-nativeasyncstorage

AsyncStorage - Is multiSet() transactional?


I have an app where I plan on pulling some data from my server and then store that data using AsyncStorage. So there won't be a need to constantly fetch my data. I fetch a couple of jsons using fetch() and then store them using AsyncStore.multiSet().

However, if there is a problem storing one of my, about 5 json objects in AsyncStorage I do not wish to store any of them. To keep the data in a correct state. Therefor I would like to store them using a transaction.

So what would happen if in the middle of storing my objects there is some problem and the storing fails. For instance if the app was closed by the user or if their battery runs out.

What would happen in a scenario like that? Could my first 2 objects be saved and the other 3 not be saved?


Solution

  • It seems like it varies based on the underlying storage implementation.

    Looking at the implementation of AsyncStorage.js, React Native looks for and uses RocksDB, then SQLite, and then AsyncLocalStorage in that order, nad uses the first one it can find.

    I couldn't seem to find any RocksDB implementation within the React Native codebase. Looking at the documentation, though, it seems as though Transactions are supported when using 'TransactionDB or OptimisticTransactionDB':

    https://github.com/facebook/rocksdb/wiki/Transactions
    

    In the case of SQLite being the underlying implementation:

    https://github.com/facebook/react-native/blob/235b16d93287061a09c4624e612b5dc4f960ce47/ReactAndroid/src/main/java/com/facebook/react/modules/storage/AsyncStorageModule.java#L147
    

    it looks as though it tries to save everything it possibly can:

      /** 
       * Inserts multiple (key, value) pairs. If one or more of the pairs cannot be inserted, this will
       * return AsyncLocalStorageFailure, but all other pairs will have been inserted.
       * The insertion will replace conflicting (key, value) pairs.
        */
      @ReactMethod
      public void multiSet(final ReadableArray keyValueArray, final Callback callback) {
    

    Finally, judging from the React Native implementation of AsyncLocalStorage, the final possibility of underlying implementation, it seems like it also saves everything it possibly can, storing the errors of the failed cases as they happen:

      for (NSArray<NSString *> *entry in kvPairs) {
        NSDictionary *keyError = [self _writeEntry:entry changedManifest:&changedManifest];
        RCTAppendError(keyError, &errors);
      }