【问题标题】:Update returning queries in ScalikeJDBC更新 ScalikeJDBC 中的返回查询
【发布时间】:2019-03-18 09:24:12
【问题描述】:

在范围内使用implicit val session: DBSession,具体为scalikejdbc.AutoSession

更新工作

sql"""
    update payments set status=${status.name} where id in ($ids)
""".update().apply()

并选择工作

sql"""
   select id
   from payments
   where status='valid'
""".map(_.long).list().apply()

但更新返回列失败,因为事务设置为只读。

sql"""
  update payments
  set status='submitted'
  where status='pending'
  and scheduled <= ${ZonedDateTime.now.toInstant}
  returning id
""".map(_.long).iterable().apply().toIterator

org.postgresql.util.PSQLException: ERROR: cannot execute UPDATE in a read-only transaction.

sessionSQLToResult 内部匹配,并假设它应该是只读的:

  case AutoSession | ReadOnlyAutoSession => DB.readOnly(f)

我尝试创建自己的DBSession 以避免匹配此模式,但放弃了该方法。我最接近让它工作的是:

val writeableSession: DBSession = DBSession(session.connection, isReadOnly = false)

def inner()(implicit session: DBSession): Iterator[Payment] = {
  sql"""
  update payments
  set status='submitted'
  where status='pending'
  returning id
""".map(_.long).iterable().apply().toIterator
}

inner()(writeableSession)

这失败了,因为 session.connectionnull

如何强制它成为 localTx 而不是 readOnly?

【问题讨论】:

    标签: scala scalikejdbc


    【解决方案1】:

    一般来说,AutoSession 表现为 DDL 和插入/更新/删除操作的自动提交会话,而它作为选择查询的只读会话。

    似乎这样做是直截了当的方式。

    DB.localTx { implicit session =>
      // Have both the update operation and select query inside this block
    }
    

    【讨论】:

    • 谢谢。是的,我更喜欢这样做,但我在 playframework 中,除了急切绑定的 Autosession 之外什么都没有。
    • 我明白了。 scalikejdbc.TxBoundary.Future 可能对您的用例有用。 scalikejdbc.org/documentation/…
    • 对不起。当然,我可以调用DB.localTx。我不知道为什么我认为我做不到。 :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-16
    • 2019-09-05
    • 1970-01-01
    • 2015-01-08
    相关资源
    最近更新 更多