select 语句引发行更新或删除错误

row update or delete error is being thrown by select statement

我有一个 scala 和 play 项目。我在某些条件下从 table 读取数据。它抛出以下错误。行已被另一个事务更新或删除(或未保存的值映射不正确):

我认为这会发生在保存或删除或更新时。它也会发生在 select select 如何解决这个问题?

代码

def deleteOutputConfig(condition: Condition, outputName: String,outputConfigId: Long): Unit = {
   val outputConfigs = jpa.em.createQuery(OutputConfigDao.getOutputConfigByConditionQuery, classOf[OutputConfig])
    .setParameter("conditionId", condition)
    .setParameter("outputName", outputName)
     .setParameter("outputConfigId",outputConfigId)
    .getResultList.asScala.toList

    if(outputConfigs.nonEmpty) {
      val outputConfig = outputConfigs.head
      outputConfig.setIsDeleted(true)
      jpa.em.persist(outputConfig)
    }
    else
      None
  }

query:
val getOutputConfigByConditionQuery = "select outputConfig from OutputConfig outputConfig where RULE_CONDITION_ID = (:conditionId) and OUTPUT_NAME = (:outputName)" +
                                          " and is_deleted=0 and output_config_id = (:outputConfigId) order by OUTPUT_CONFIG_ID desc"

这是完整的错误

javax.persistence.OptimisticLockException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [com.octanner.common.entity.BankAccount#1541668]
    at org.hibernate.ejb.AbstractEntityManagerImpl.wrapStaleStateException(AbstractEntityManagerImpl.java:1413)
    at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1329)
    at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1310)
    at org.hibernate.ejb.QueryImpl.getResultList(QueryImpl.java:277)
    at dao.OutputConfigDao.deleteOutputConfig(OutputConfigDao.scala:41)
    at services.DepositService.deleteDepositRuleRun(DepositService.scala:154)
    at services.DepositService.$anonfun$processDepositDetails(DepositService.scala:115)
    at scala.runtime.java8.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.java:12)
    at scala.util.Try$.apply(Try.scala:209)
    at services.DepositService.processDepositDetails(DepositService.scala:87)
    at services.DepositService.$anonfun$depositDetails(DepositService.scala:66)
    at scala.runtime.java8.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.java:12)
    at scala.util.Try$.apply(Try.scala:209)
    at services.DepositService.$anonfun$depositDetails(DepositService.scala:56)
    at scala.collection.immutable.List.foreach(List.scala:389)
    at services.DepositService.$anonfun$depositDetails(DepositService.scala:54)
    at scala.runtime.java8.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.java:12)
    at services.package$$anon.get(package.scala:12)
    at play.db.jpa.DefaultJPAApi.lambda$withTransaction(DefaultJPAApi.java:207)
    at play.db.jpa.DefaultJPAApi.withTransaction(DefaultJPAApi.java:142)
    at play.db.jpa.DefaultJPAApi.withTransaction(DefaultJPAApi.java:206)
    at play.db.jpa.DefaultJPAApi.withTransaction(DefaultJPAApi.java:179)
    at services.package$.runInTransaction(package.scala:11)
    at services.DepositService.depositDetails(DepositService.scala:54)
    at controllers.DepositController.$anonfun$processDepositForm(DepositController.scala:148)
    at controllers.DepositController.$anonfun$processDepositForm$adapted(DepositController.scala:147)
    at scala.util.Success.$anonfun$map(Try.scala:251)
    at scala.util.Success.map(Try.scala:209)
    at scala.concurrent.Future.$anonfun$map(Future.scala:288)
    at scala.concurrent.impl.Promise.liftedTree1(Promise.scala:29)
    at scala.concurrent.impl.Promise.$anonfun$transform(Promise.scala:29)
    at scala.concurrent.impl.CallbackRunnable.run(Promise.scala:60)
    at akka.dispatch.BatchingExecutor$AbstractBatch.processBatch(BatchingExecutor.scala:55)
    at akka.dispatch.BatchingExecutor$BlockableBatch.$anonfun$run(BatchingExecutor.scala:91)
    at scala.runtime.java8.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.java:12)
    at scala.concurrent.BlockContext$.withBlockContext(BlockContext.scala:81)
    at akka.dispatch.BatchingExecutor$BlockableBatch.run(BatchingExecutor.scala:91)
    at akka.dispatch.TaskInvocation.run(AbstractDispatcher.scala:40)
    at akka.dispatch.ForkJoinExecutorConfigurator$AkkaForkJoinTask.exec(ForkJoinExecutorConfigurator.scala:44)
    at akka.dispatch.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260)
    at akka.dispatch.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1339)
    at akka.dispatch.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979)
    at akka.dispatch.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107)
Caused by: org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [com.octanner.common.entity.BankAccount#1541668]
    at org.hibernate.persister.entity.AbstractEntityPersister.check(AbstractEntityPersister.java:2523)
    at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:3242)
    at org.hibernate.persister.entity.AbstractEntityPersister.updateOrInsert(AbstractEntityPersister.java:3140)
    at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:3470)
    at org.hibernate.action.internal.EntityUpdateAction.execute(EntityUpdateAction.java:140)
    at org.hibernate.engine.spi.ActionQueue.execute(ActionQueue.java:393)
    at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:385)
    at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:302)
    at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:339)
    at org.hibernate.event.internal.DefaultAutoFlushEventListener.onAutoFlush(DefaultAutoFlushEventListener.java:62)
    at org.hibernate.internal.SessionImpl.autoFlushIfRequired(SessionImpl.java:1211)
    at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1268)
    at org.hibernate.internal.QueryImpl.list(QueryImpl.java:101)
    at org.hibernate.ejb.QueryImpl.getResultList(QueryImpl.java:268)

当多个事务访问相同的代码时,您需要将代码保留在临界区中。 将导致问题的代码放在同步块中,这将有助于解决问题。

this.synchronized {

place your code here
}

因此一次只有一个事务可以访问它并保存数据,其他事务将等待。确保获取其他交易的最新数据