更新 ScalikeJDBC 中的返回查询
Update returning queries in ScalikeJDBC
范围为 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
.
session
在 SQLToResult
内匹配,假设它应该是只读的:
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.connection
是 null
。
如何将其强制为 localTx 而不是 readOnly?
一般来说,AutoSession
表现为 DDL 和 insert/update/delete 操作的自动提交会话,而它作为 select 查询的只读会话。
看来直接按照下面的方法做就好了
DB.localTx { implicit session =>
// Have both the update operation and select query inside this block
}
范围为 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
.
session
在 SQLToResult
内匹配,假设它应该是只读的:
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.connection
是 null
。
如何将其强制为 localTx 而不是 readOnly?
一般来说,AutoSession
表现为 DDL 和 insert/update/delete 操作的自动提交会话,而它作为 select 查询的只读会话。
看来直接按照下面的方法做就好了
DB.localTx { implicit session =>
// Have both the update operation and select query inside this block
}