Транзакция базы данных Vapor Fluent не является атомарной - PullRequest
1 голос
/ 25 мая 2019

Я создаю транзакцию 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 ), и вся транзакция будет возвращена правильно.

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

1 Ответ

1 голос
/ 25 мая 2019

Я не уверен насчет конструкций в вашем примере кода и особенно об ошибке 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())
    }
}

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

...