Транзакция базы данных Vapor Fluent не является атомарной

Создаю database транзакцию с несколькими вставками внутри нее. Результаты сохраняются как array будущего. Затем ищу результаты операции в do{..}.catch{..} строительстве. А вот и

проблема: если я возвращаю неудавшееся будущее из блока do, то вся транзакция откатывается - хорошо, но если я возвращаю такое же неудачное будущее из блока «catch», тогда некоторые записи фиксируются в базе данных.

    func save(on req: Request) -> Future<Confirmation>
    {
      return req.transaction(on: .psql) { conn in
      let promise = conn.eventLoop.newPromise(Confirmation.self)
      var futures = [Future<Bool>]()
       for i in 0 ..< 20 
       {
         let g1 = Group()
         g1.name = "\(i)"
         let f1 = g1.save(on: conn).then { _ -> Future<Bool> in
         if i == 15
         {
//          return conn.eventLoop.newSucceededFuture(result: false) //1
            return conn.eventLoop.newFailedFuture(error: SyncError.nullPrimaryKey) // 2
          } 
          else 
          {
            return conn.eventLoop.newSucceededFuture(result: true)
          }
        }
        futures.append(f1)
      }

      futures.do(on: conn){ results in
        var res = true
        results.forEach { e in
          res = res && e
        }
        if res {
          promise.succeed(result: Confirmation())
        } 
        else {
          promise.fail(error: SyncError.nullPrimaryKey) // 3
         }
        }.catch { e in
         promise.fail(error: e) // 4
     }
     return promise.futureResult
    }
  }
}

В этом примере обещание выполняется с ошибкой в ​​строке 4 (блок catch), и у меня проблема с неотвернутой транзакцией. Но если я закомментирую строку 1 и раскомментирую строку 2, тогда обещание будет выполнено в строке 3 (блок do), и вся транзакция будет отменена правильно.

Это моя ошибка где-то в коде или это ошибка Fluent?


person Vas    schedule 25.05.2019    source источник


Ответы (1)


Я не уверен насчет конструкций в вашем примере кода и особенно об ошибке SyncError.nullPrimaryKey в if i == 15, но похоже, что код ниже делает то же самое

func save(_ req: Request) throws -> Future<Confirmation> {
    return req.transaction(on: .psql) { conn in
        return (0...15).map {
            Group(name: $0)
        }.map {
            $0.save(on: conn).transform(to: ())
        }.flatten(on: conn).transform(to: Confirmation())
    }
}

Надеюсь, это поможет

person imike    schedule 25.05.2019