From 50b2c595721447d704715c11f14fdd276bd8f705 Mon Sep 17 00:00:00 2001 From: Raphael Speyer Date: Fri, 19 May 2023 04:55:12 +1000 Subject: [PATCH] Make template id lookup concurrency-safe. (#16883) --- .../digitalasset/http/dbbackend/Queries.scala | 46 +++++++++++++------ 1 file changed, 32 insertions(+), 14 deletions(-) diff --git a/ledger-service/db-backend/src/main/scala/com/digitalasset/http/dbbackend/Queries.scala b/ledger-service/db-backend/src/main/scala/com/digitalasset/http/dbbackend/Queries.scala index 83ecb1cd4e0..13c05810f08 100644 --- a/ledger-service/db-backend/src/main/scala/com/digitalasset/http/dbbackend/Queries.scala +++ b/ledger-service/db-backend/src/main/scala/com/digitalasset/http/dbbackend/Queries.scala @@ -23,7 +23,6 @@ import scalaz.std.AllInstances._ import spray.json._ import cats.instances.list._ import cats.Applicative -import cats.syntax.applicative._ import cats.syntax.functor._ import com.daml.http.metrics.HttpJsonApiMetrics import com.daml.http.util.Logging.InstanceUUID @@ -189,19 +188,19 @@ sealed abstract class Queries(tablePrefix: String, tpIdCacheMaxEntries: Long)(im private def surrogateTemplateIdFromDb(packageId: String, moduleName: String, entityName: String)( implicit log: LogHandler - ): ConnectionIO[SurrogateTpId] = - sql"""SELECT tpid FROM $templateIdTableName - WHERE (package_id = $packageId AND template_module_name = $moduleName - AND template_entity_name = $entityName)""" - .query[SurrogateTpId] - .option flatMap { - _.cata( - _.pure[ConnectionIO], - sql"""INSERT INTO $templateIdTableName (package_id, template_module_name, template_entity_name) - VALUES ($packageId, $moduleName, $entityName)""".update - .withUniqueGeneratedKeys[SurrogateTpId]("tpid"), - ) - } + ): ConnectionIO[SurrogateTpId] = for { + _ <- insertTemplateIdIfNotExists(packageId, moduleName, entityName).update.run + tpid <- sql"""SELECT tpid FROM $templateIdTableName + WHERE (package_id = $packageId AND template_module_name = $moduleName + AND template_entity_name = $entityName)""".query[SurrogateTpId].unique + + } yield tpid + + protected def insertTemplateIdIfNotExists( + packageId: String, + moduleName: String, + entityName: String, + ): Fragment final def lastOffset(parties: PartySet, tpid: SurrogateTpId)(implicit log: LogHandler @@ -849,6 +848,16 @@ private final class PostgresQueries(tablePrefix: String, tpIdCacheMaxEntries: Lo } sql"${fragmentContractPath(path)} $opc ${literalScalar}::jsonb" } + + protected override def insertTemplateIdIfNotExists( + packageId: String, + moduleName: String, + entityName: String, + ): Fragment = + sql"""INSERT INTO $templateIdTableName (package_id, template_module_name, template_entity_name) + VALUES ($packageId, $moduleName, $entityName) + ON CONFLICT (package_id, template_module_name, template_entity_name) DO NOTHING""" + } import OracleQueries.DisableContractPayloadIndexing @@ -1126,6 +1135,15 @@ private final class OracleQueries( sql"JSON_EXISTS($contractColumnName, " ++ sql"""${oracleShortPathEscape(pathc)}${passingValueAsX})""" } + + protected override def insertTemplateIdIfNotExists( + packageId: String, + moduleName: String, + entityName: String, + ): Fragment = + sql"""INSERT /*+ ignore_row_on_dupkey_index($templateIdTableName(package_id, template_module_name, template_entity_name)) */ + INTO $templateIdTableName (package_id, template_module_name, template_entity_name) + VALUES ($packageId, $moduleName, $entityName)""" } private[http] object OracleQueries {