@Transactional 在 Spring 使用自定义事务管理器启动时不起作用
@Transactional not working in Spring Boot with a custom Transaction Manager
我正在尝试编写自己的自定义 PlatformTransactionManager 以与 Neo4J 一起使用(注意 - 由于各种原因我不想使用 OGM,这意味着不使用 Spring 数据)。
我编写了一个非常简单的 Neo4jTransactionManager 并将其添加到我的上下文中,以及 @EnableTransactionManagement 注释,然后将 @Transactonal 添加到我的健康检查中 - 它没有触发任何东西。
代码如下:(注-Neo4jOperations是Driver的包装器,使调用数据库更容易,类似于JdbcOperations)
class Neo4jTransactionManager(private val driver: Driver) : AbstractPlatformTransactionManager() {
companion object {
private val LOG = LoggerFactory.getLogger(Neo4jTransactionManager::class.java)
}
class Neo4jTransaction(private val driver: Driver) {
var session: Session? = null
var transaction: Transaction? = null
fun start() {
if (session != null) {
throw CannotCreateTransactionException("Transaction already started")
}
session = driver.session()
transaction = session?.beginTransaction()
}
}
override fun doCommit(status: DefaultTransactionStatus) {
val transaction = unwrapTransaction(status)
LOG.debug("Committing transaction: {}", transaction)
if (transaction.transaction == null) {
throw NoTransactionException("No current transaction")
}
transaction.transaction?.success()
transaction.transaction?.close()
transaction.session?.close()
}
override fun doBegin(transaction: Any, definition: TransactionDefinition) {
(transaction as Neo4jTransaction).start()
}
override fun doGetTransaction(): Any {
return Neo4jTransaction(driver)
}
override fun doRollback(status: DefaultTransactionStatus) {
val transaction = unwrapTransaction(status)
LOG.debug("Rolling back transaction: {}", transaction)
if (transaction.transaction == null) {
throw NoTransactionException("No current transaction")
}
transaction.transaction?.failure()
transaction.transaction?.close()
transaction.session?.close()
}
private fun unwrapTransaction(status: DefaultTransactionStatus) : Neo4jTransaction {
return status.transaction as Neo4jTransaction
}
}
@Configuration
@EnableTransactionManagement(proxyTargetClass = true, mode = AdviceMode.PROXY)
class DatabaseConfig {
.....
@Bean("transactionManager")
fun neo4jTransactionManager(driver: Driver) = Neo4jTransactionManager(driver)
@Bean
fun neo4jHealthcheck(neo4jOperations: Neo4jOperations) = Neo4jHealthcheck(neo4jOperations)
}
@Transactional
class Neo4jHealthcheck(private val neo4jOperations: Neo4jOperations) : AbstractHealthIndicator() {
companion object {
private const val QUERY = "MATCH (n) RETURN count(*) as count"
}
@Transactional
override fun doHealthCheck(builder: Health.Builder) {
val count = neo4jOperations.queryOne(QUERY).get("count").asInt()
builder.up()
.withDetail("Nodes", count)
.build()
}
}
我希望看到我的健康检查发出一些关于交易内容的日志消息,并在调试时在堆栈跟踪中看到它们。但我没有看到任何这些,所以它几乎就好像它完全忽略了我的@Transactional 注释。
我错过了什么?
干杯
据我所知,Neo4jHealthcheck 不是 spring 组件。所以可能没有创建代理。
您必须将 @Component 或任何子类型添加到 Neo4jHealthcheck
查看执行器和事务的示例:
我正在尝试编写自己的自定义 PlatformTransactionManager 以与 Neo4J 一起使用(注意 - 由于各种原因我不想使用 OGM,这意味着不使用 Spring 数据)。
我编写了一个非常简单的 Neo4jTransactionManager 并将其添加到我的上下文中,以及 @EnableTransactionManagement 注释,然后将 @Transactonal 添加到我的健康检查中 - 它没有触发任何东西。
代码如下:(注-Neo4jOperations是Driver的包装器,使调用数据库更容易,类似于JdbcOperations)
class Neo4jTransactionManager(private val driver: Driver) : AbstractPlatformTransactionManager() {
companion object {
private val LOG = LoggerFactory.getLogger(Neo4jTransactionManager::class.java)
}
class Neo4jTransaction(private val driver: Driver) {
var session: Session? = null
var transaction: Transaction? = null
fun start() {
if (session != null) {
throw CannotCreateTransactionException("Transaction already started")
}
session = driver.session()
transaction = session?.beginTransaction()
}
}
override fun doCommit(status: DefaultTransactionStatus) {
val transaction = unwrapTransaction(status)
LOG.debug("Committing transaction: {}", transaction)
if (transaction.transaction == null) {
throw NoTransactionException("No current transaction")
}
transaction.transaction?.success()
transaction.transaction?.close()
transaction.session?.close()
}
override fun doBegin(transaction: Any, definition: TransactionDefinition) {
(transaction as Neo4jTransaction).start()
}
override fun doGetTransaction(): Any {
return Neo4jTransaction(driver)
}
override fun doRollback(status: DefaultTransactionStatus) {
val transaction = unwrapTransaction(status)
LOG.debug("Rolling back transaction: {}", transaction)
if (transaction.transaction == null) {
throw NoTransactionException("No current transaction")
}
transaction.transaction?.failure()
transaction.transaction?.close()
transaction.session?.close()
}
private fun unwrapTransaction(status: DefaultTransactionStatus) : Neo4jTransaction {
return status.transaction as Neo4jTransaction
}
}
@Configuration
@EnableTransactionManagement(proxyTargetClass = true, mode = AdviceMode.PROXY)
class DatabaseConfig {
.....
@Bean("transactionManager")
fun neo4jTransactionManager(driver: Driver) = Neo4jTransactionManager(driver)
@Bean
fun neo4jHealthcheck(neo4jOperations: Neo4jOperations) = Neo4jHealthcheck(neo4jOperations)
}
@Transactional
class Neo4jHealthcheck(private val neo4jOperations: Neo4jOperations) : AbstractHealthIndicator() {
companion object {
private const val QUERY = "MATCH (n) RETURN count(*) as count"
}
@Transactional
override fun doHealthCheck(builder: Health.Builder) {
val count = neo4jOperations.queryOne(QUERY).get("count").asInt()
builder.up()
.withDetail("Nodes", count)
.build()
}
}
我希望看到我的健康检查发出一些关于交易内容的日志消息,并在调试时在堆栈跟踪中看到它们。但我没有看到任何这些,所以它几乎就好像它完全忽略了我的@Transactional 注释。
我错过了什么?
干杯
据我所知,Neo4jHealthcheck 不是 spring 组件。所以可能没有创建代理。
您必须将 @Component 或任何子类型添加到 Neo4jHealthcheck
查看执行器和事务的示例: