如何清理 Spring 引导应用程序中的数据库表?
How to vacuum database tables in a Spring Boot application?
我目前的尝试(根据 )如下所示:
@Service
class VacuumDatabaseService(
private val entityManager: EntityManager
) {
fun vacuumAllTables() {
val session = entityManager.unwrap(org.hibernate.Session::class.java)
val sessionImpl = session as org.hibernate.internal.SessionImpl
val connection = sessionImpl.connection()
connection.prepareStatement("VACUUM FULL").execute()
}
}
但它抛出:
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is java.lang.IllegalStateException: No transactional EntityManager available
用 @Transactional
注释函数导致:
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is java.lang.reflect.UndeclaredThrowableException
Caused by: org.postgresql.util.PSQLException: ERROR: VACUUM cannot run inside a transaction block
以下有效,但感觉错误得很危险:
@Transactional
fun vacuumAllTables() {
val session = entityManager.unwrap(org.hibernate.Session::class.java)
val sessionImpl = session as org.hibernate.internal.SessionImpl
val connection = sessionImpl.connection()
connection.prepareStatement("END TRANSACTION; VACUUM FULL;").execute()
}
正确的方法是什么?
您只需注入 DataSource
,从中获取连接,执行作业,然后关闭连接。
@Service
class VacuumDatabaseService(
private val dataSource: DataSource
) {
fun vacuumAllTables() {
dataSource.connection.use {
it.prepareStatement("VACUUM FULL").execute()
}
}
}
注意 use
的用法,它会在块执行后关闭连接。
我目前的尝试(根据
@Service
class VacuumDatabaseService(
private val entityManager: EntityManager
) {
fun vacuumAllTables() {
val session = entityManager.unwrap(org.hibernate.Session::class.java)
val sessionImpl = session as org.hibernate.internal.SessionImpl
val connection = sessionImpl.connection()
connection.prepareStatement("VACUUM FULL").execute()
}
}
但它抛出:
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is java.lang.IllegalStateException: No transactional EntityManager available
用 @Transactional
注释函数导致:
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is java.lang.reflect.UndeclaredThrowableException
Caused by: org.postgresql.util.PSQLException: ERROR: VACUUM cannot run inside a transaction block
以下有效,但感觉错误得很危险:
@Transactional
fun vacuumAllTables() {
val session = entityManager.unwrap(org.hibernate.Session::class.java)
val sessionImpl = session as org.hibernate.internal.SessionImpl
val connection = sessionImpl.connection()
connection.prepareStatement("END TRANSACTION; VACUUM FULL;").execute()
}
正确的方法是什么?
您只需注入 DataSource
,从中获取连接,执行作业,然后关闭连接。
@Service
class VacuumDatabaseService(
private val dataSource: DataSource
) {
fun vacuumAllTables() {
dataSource.connection.use {
it.prepareStatement("VACUUM FULL").execute()
}
}
}
注意 use
的用法,它会在块执行后关闭连接。