Transactions With JSONCollection instead of BSONCollection

社会主义新天地 提交于 2020-08-10 18:57:05

问题


I have a problem to make Transaction via JSONCollection, I getting the following error:

JsResultException(errors:List((,List(JsonValidationError(List(CommandError[code=14, errmsg=BSON field 'OperationSessionInfo.txnNumber' is the wrong type 'int', expected type 'long', doc: {"operationTime":{"$time":1596894245,"$i":5,"$timestamp":{"t":1596894245,"i":5}},"ok":0,"errmsg":"BSON field 'OperationSessionInfo.txnNumber' is the wrong type 'int', expected type 'long'","code":14,"codeName":"TypeMismatch","$clusterTime":{"clusterTime":{"$time":1596894245,"$i":5,"$timestamp":{"t":1596894245,"i":5}},"signature":{"hash":{"$binary":"0000000000000000000000000000000000000000","$type":"00"},"keyId":0}}}]),WrappedArray())))))

I tried to change my project to BSONCollection but got some troubles, maybe there solution to overcome the above error with JSONCollection. Also the exceptions occurs on testing update method, but checking the insertOneViaTransaction and setRuleAsInactiveViaTransaction is finished with success This is my code for Transaction: Update:

 def update(oldRule: ExistRuleDto): Future[UpdateResult] = {
    val transaction = (collection: JSONCollection) => for {
      newRule <- dao.insertOneViaTransaction(collection,oldRule.toUpdatedRule) // insert new with ref to old
      oldRule <- dao.setRuleAsInactiveViaTransaction(collection,oldRule.id)
    } yield UpdateResult(oldRule, newRule)

      makeTransaction[UpdateResult](transaction)
  }

makeTransaction:

def makeTransaction[Out](block: JSONCollection => Future[Out]): Future[Out] = for {
    dbWithSession <- dao.collection.db.startSession()
    dbWithTx <- dbWithSession.startTransaction(None)
    coll = dbWithTx.collection[JSONCollection](dao.collection.name)

    // Operations:
    res <- block(coll)

    _ <- dbWithTx.commitTransaction()
    _ <- dbWithSession.endSession()
  } yield res

insertOneViaTransaction:

  def insertOneViaTransaction(collection: JSONCollection, rule: Rule): Future[Rule] = {
    collection.insert.one(rule).map {
      case DefaultWriteResult(true, 1, _, _, _, _) => rule
      case err => throw GeneralDBError(s"$rule was not inserted, something went wrong: $err")
    }.recover {
        case WriteResult.Code(11000) => throw DuplicationError(s"$rule exist on DB")
        case err => throw GeneralDBError(err.getMessage)
      }
  }

setRuleAsInactiveViaTransaction:

 def setRuleAsInactiveViaTransaction(collection: JSONCollection, ruleId: BSONObjectID): Future[Rule] = {
    collection.findAndUpdate(
      Json.obj(s"${Rule.ID}" -> ruleId),
      Json.obj(
        "$set" -> Json.obj(s"${Rule.Metadata}.${Metadata.Active}" -> false),
        "$unset" -> Json.obj(s"${Rule.Metadata}.${Metadata.LastVersionExists}" -> "")),
    fetchNewObject = true, upsert = false, sort = None, fields = None, bypassDocumentValidation = false, writeConcern = WriteConcern.Acknowledged, maxTime = None, collation = None, arrayFilters = Nil
    ).map(el => el.result[Rule].getOrElse {
      val msg = s"Operation fail for updating ruleId = $ruleId"
      logger.error(msg)
      throw GeneralUpdateError(msg)
    })
  }

I'm using the following dependencies: Play:

    "com.typesafe.play" % "sbt-plugin" % "2.7.2

Reactivemongo:

    "org.reactivemongo" %% "play2-reactivemongo" % "0.18.8-play27"

来源:https://stackoverflow.com/questions/63316206/transactions-with-jsoncollection-instead-of-bsoncollection

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!