ホーム>source

Neo4Jを操作するための独自のカスタムPlatformTransactionManagerを作成しようとしています(注-さまざまな理由でOGMを使用したくないため、Spring Dataを使用しません)。

非常にシンプルなNeo4jTransactionManagerを作成し、それをコンテキストに追加し、@ EnableTransactionManagementアノテーションを追加してから、@ Transactonalをヘルスチェックに追加しましたが、何もトリガーしません。

コードは次のとおりです(注-Neo4jOperationsは、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アノテーションを完全に無視しているように見えます。

私は何を見逃しましたか?

乾杯

あなたの答え
  • 解決した方法 # 1

    Neo4jHealthcheckはスプリングコンポーネントではありません。したがって、プロキシが作成されていない可能性があります。

    Neo4jHealthcheckに@Componentまたはサブタイプのいずれかを追加する必要があります

    実行者とトランザクションの例をご覧ください。

    https://github.com/simasch/actuator-transactional

関連記事

  • 前へ java - JPAクエリ:サブクエリをグループ化条件に結合する
  • 次へ jquery - オブジェクトが存在しない場合はJSON配列にプッシュします