title: How can I make multiple calls of NSBatchUpdateRequest within DB transaction so that either all rows is updated or none is updated?
body: <p>Is there a way, to make multiple <code>NSBatchUpdateRequest</code> calls executed within a DB transaction, so that either all DB rows is updated or none is updated (When exception thrown)?</p>
  <p>The following code illustrate the problem.</p>
  <hr />
  <pre><code>func debug() {
      let coreDataStack = CoreDataStack.INSTANCE
      let backgroundContext = coreDataStack.backgroundContext
      
      backgroundContext.perform {
          let fetchRequest = NSTabInfo.fetchSortedRequest()
          
          do {
              var objectIDs: [NSManagedObjectID] = []
              
              let nsTabInfos = try fetchRequest.execute()
              
              //
              // QUESTION: We are updating multiple rows of data directly in a persistent store.
              // How can we ensure either all rows is updated, or none row is updated is exception
              // happens in between?
              //
              for nsTabInfo in nsTabInfos {
                  let batchUpdateRequest = NSBatchUpdateRequest(entityName: &quot;NSTabInfo&quot;)
                  batchUpdateRequest.predicate = NSPredicate(format: &quot;self == %@&quot;, nsTabInfo.objectID)
                  batchUpdateRequest.propertiesToUpdate = [&quot;name&quot;: nsTabInfo.name! + &quot;XXX&quot;]
                  batchUpdateRequest.resultType = .updatedObjectIDsResultType
                  
                  let batchUpdateResult = try backgroundContext.execute(batchUpdateRequest) as? NSBatchUpdateResult
                  
                  guard let batchUpdateResultX = batchUpdateResult else { return }
                  guard let managedObjectIDs = batchUpdateResultX.result else { return }
  
                  if let nsManagedObjectIDs = managedObjectIDs as? [NSManagedObjectID] {
                      objectIDs.append(contentsOf: nsManagedObjectIDs)
                  }
                  
                  //
                  // Simulate some exception
                  // We notice the first row is updated &amp; rest of the rows are unchanged.
                  // This leaves our data in inconsistent state.
                  //
                  throw &quot;Custom error!!!&quot;
              }
              
              if !objectIDs.isEmpty {
                  let changes = [NSUpdatedObjectsKey : objectIDs]
                  coreDataStack.mergeChanges(changes)
              }
              
          } catch {
              backgroundContext.rollback()
              
              error_log(error)
          }
      }
  }
  
  class CoreDataStack {
      static let INSTANCE = CoreDataStack()
      
      private init() {
      }
      
      private(set) lazy var persistentContainer: NSPersistentContainer = {
          let container = NSPersistentContainer(name: &quot;wenote&quot;)
          
          container.loadPersistentStores(completionHandler: { (storeDescription, error) in
              if let error = error as NSError? {
                  fatalError(&quot;Unresolved error \(error), \(error.userInfo)&quot;)
              }
          })
          
          // So that when backgroundContext write to persistent store, container.viewContext will retrieve update from
          // persistent store.
          container.viewContext.automaticallyMergesChangesFromParent = true
          
          return container
      }()
      
      private(set) lazy var backgroundContext: NSManagedObjectContext = {
          let backgroundContext = persistentContainer.newBackgroundContext()
  
          backgroundContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy
          
          return backgroundContext
      }()
      
  
      func mergeChanges(_ changes: [AnyHashable : Any]) {
          
          NSManagedObjectContext.mergeChanges(
              fromRemoteContextSave: changes,
              into: [persistentContainer.viewContext, backgroundContext]
          )
      }
  }
  </code></pre>
  <hr />
  <p>We write a demo code to illustrate the following</p>
  <ol>
  <li>Performing <code>NSBatchUpdateRequest</code> multiple times within a loop.</li>
  <li>An exception happens in between.</li>
  <li>We wishes none of the row in persistent store is updated. However, a row is already updated before the exception thrown.</li>
  </ol>
  <p>May I know what technique I can use, which is similar to SQLite transaction feature, so that either all rows is updated, or none of the row is updated when exception happens?</p>