feat: トランザクションの問題で正常にドメインイベントを受け取ったあとの処理を実行できなかった問題を修正

This commit is contained in:
usbharu 2024-08-16 14:25:26 +09:00
parent 8d244b74c1
commit e9d776f71a
Signed by: usbharu
GPG Key ID: 6556747BF94EEBC8
8 changed files with 74 additions and 22 deletions

View File

@ -2,16 +2,12 @@ package dev.usbharu.hideout.core.domain.shared.repository
import dev.usbharu.hideout.core.domain.shared.domainevent.DomainEventPublisher
import dev.usbharu.hideout.core.domain.shared.domainevent.DomainEventStorable
import org.jetbrains.exposed.sql.transactions.TransactionManager
import org.springframework.stereotype.Repository
@Repository
interface DomainEventPublishableRepository<T : DomainEventStorable> {
val domainEventPublisher: DomainEventPublisher
suspend fun update(entity: T) {
println(entity.getDomainEvents().joinToString())
val current = TransactionManager.current()
current.registerInterceptor()
entity.getDomainEvents().distinctBy {
if (it.collectable) {
it.name

View File

@ -17,6 +17,10 @@
package dev.usbharu.hideout.core.infrastructure.exposedrepository
import dev.usbharu.hideout.core.domain.exception.SpringDataAccessExceptionSQLExceptionTranslator
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.slf4j.MDCContext
import org.jetbrains.exposed.sql.Transaction
import org.jetbrains.exposed.sql.statements.StatementInterceptor
import org.jetbrains.exposed.sql.transactions.TransactionManager
import org.slf4j.Logger
import org.springframework.beans.factory.annotation.Value
@ -35,7 +39,20 @@ abstract class AbstractRepository {
@Value("\${hideout.debug.trace-query-call:false}")
private var traceQueryCall: Boolean = false
protected suspend fun <T> query(block: () -> T): T = try {
class TransactionInterceptor(private val transaction: Transaction) {
fun onComplete(block: suspend (transaction: Transaction) -> Unit) {
transaction.registerInterceptor(object : StatementInterceptor {
override fun afterCommit(transaction: Transaction) {
runBlocking(MDCContext()) {
block(transaction)
}
}
})
}
}
protected suspend fun <T> query(block: TransactionInterceptor.() -> T): T = try {
if (traceQueryCall) {
@Suppress("ThrowingExceptionsWithoutMessageOrCause")
logger.trace(
@ -49,7 +66,7 @@ ${Throwable().stackTrace.joinToString("\n")}
)
}
block.invoke()
block.invoke(TransactionInterceptor(TransactionManager.current()))
} catch (e: SQLException) {
if (traceQueryException) {
logger.trace("FAILED EXECUTE SQL", e)

View File

@ -45,8 +45,11 @@ class ExposedActorInstanceRelationshipRepository(override val domainEventPublish
it[muting] = actorInstanceRelationship.muting
it[doNotSendPrivate] = actorInstanceRelationship.doNotSendPrivate
}
onComplete {
update(actorInstanceRelationship)
}
}
update(actorInstanceRelationship)
return actorInstanceRelationship
}
@ -56,8 +59,11 @@ class ExposedActorInstanceRelationshipRepository(override val domainEventPublish
actorId eq actorInstanceRelationship.actorId.id and
(instanceId eq actorInstanceRelationship.instanceId.instanceId)
}
onComplete {
update(actorInstanceRelationship)
}
}
update(actorInstanceRelationship)
}
override suspend fun findByActorIdAndInstanceId(

View File

@ -59,8 +59,11 @@ class ExposedActorRepository(
this[ActorsAlsoKnownAs.actorId] = actor.id.id
this[ActorsAlsoKnownAs.alsoKnownAs] = it.id
}
onComplete {
update(actor)
}
}
update(actor)
return actor
}
@ -68,8 +71,10 @@ class ExposedActorRepository(
query {
Actors.deleteWhere { id eq actor.id.id }
ActorsAlsoKnownAs.deleteWhere { actorId eq actor.id.id }
onComplete {
update(actor)
}
}
update(actor)
}
override suspend fun findById(id: ActorId): Actor? {

View File

@ -98,8 +98,11 @@ class ExposedPostRepository(
this[PostsVisibleActors.postId] = post.id.id
this[PostsVisibleActors.actorId] = it.id
}
onComplete {
update(post)
}
}
update(post)
return post
}
@ -148,9 +151,11 @@ class ExposedPostRepository(
this[PostsVisibleActors.postId] = it.first
this[PostsVisibleActors.actorId] = it.second
}
}
posts.forEach {
update(it)
onComplete {
posts.forEach {
update(it)
}
}
}
return posts
}
@ -195,8 +200,11 @@ class ExposedPostRepository(
Posts.deleteWhere {
id eq post.id.id
}
onComplete {
update(post)
}
}
update(post)
}
override suspend fun findByActorIdAndVisibilityInList(

View File

@ -47,8 +47,11 @@ class ExposedRelationshipRepository(override val domainEventPublisher: DomainEve
it[followRequesting] = relationship.followRequesting
it[mutingFollowRequest] = relationship.mutingFollowRequest
}
onComplete {
update(relationship)
}
}
update(relationship)
return relationship
}
@ -57,8 +60,11 @@ class ExposedRelationshipRepository(override val domainEventPublisher: DomainEve
Relationships.deleteWhere {
actorId eq relationship.actorId.id and (targetActorId eq relationship.targetActorId.id)
}
onComplete {
update(relationship)
}
}
update(relationship)
}
override suspend fun findByActorIdAndTargetId(actorId: ActorId, targetId: ActorId): Relationship? = query {

View File

@ -24,8 +24,12 @@ class ExposedTimelineRepository(override val domainEventPublisher: DomainEventPu
it[visibility] = timeline.visibility.name
it[isSystem] = timeline.isSystem
}
onComplete {
update(timeline)
}
}
update(timeline)
return timeline
}
@ -34,8 +38,11 @@ class ExposedTimelineRepository(override val domainEventPublisher: DomainEventPu
Timelines.deleteWhere {
Timelines.id eq timeline.id.value
}
onComplete {
update(timeline)
}
}
update(timeline)
}
override suspend fun findByIds(ids: List<TimelineId>): List<Timeline> {

View File

@ -48,6 +48,7 @@ class UserDetailRepositoryImpl(override val domainEventPublisher: DomainEventPub
it[password] = userDetail.password.password
it[autoAcceptFolloweeFollowRequest] = userDetail.autoAcceptFolloweeFollowRequest
it[lastMigration] = userDetail.lastMigration
it[homeTimelineId] = userDetail.homeTimelineId?.value
}
} else {
UserDetails.update({ UserDetails.id eq userDetail.id.id }) {
@ -55,20 +56,26 @@ class UserDetailRepositoryImpl(override val domainEventPublisher: DomainEventPub
it[password] = userDetail.password.password
it[autoAcceptFolloweeFollowRequest] = userDetail.autoAcceptFolloweeFollowRequest
it[lastMigration] = userDetail.lastMigration
it[homeTimelineId] = userDetail.homeTimelineId?.value
}
}
onComplete {
update(userDetail)
}
userDetail
}
update(userDetail)
return userDetail1
}
override suspend fun delete(userDetail: UserDetail): Unit {
query {
UserDetails.deleteWhere { id eq userDetail.id.id }
onComplete {
update(userDetail)
}
}
update(userDetail)
}
override suspend fun findByActorId(actorId: Long): UserDetail? = query {