运行三腿交易时避免僵局



在会计系统中,可以在帐户之间转移资金。

在双重预订交易(帐户之间的转移(转移到帐户到帐户时,

基于ID订单:

@Transactional
    override fun doubleBookPrepaid(eventId: Long, srcPurposefulAccountId: PurposefulAccountId, trgPurposefulAccountId: PurposefulAccountId, amount: Money): Pair<Money, Money>? =
        if (srcPurposefulAccountId.accountId < trgPurposefulAccountId.accountId) { // Locking minimal account ID first, to prevent deadlocks.
            val srcBooking = bookPrepaid(eventId, srcPurposefulAccountId, -amount)
            val trgBooking = bookPrepaid(eventId, trgPurposefulAccountId, amount)
            T(srcBooking, trgBooking)
        }
        else {
            val trgBooking = bookPrepaid(eventId, trgPurposefulAccountId, amount)
            val srcBooking = bookPrepaid(eventId, srcPurposefulAccountId, -amount)
            T(srcBooking, trgBooking)
        }

如何完成三腿事务的相同结果?在这种交易中,一个帐户将在同一交易中转移到两个帐户:

data class PurposefulAccountTransfer(val trgPurposefulAccountId: PurposefulAccountId, val amount: Money)
    @Transactional
    fun threeLegBookPrepaid(eventId: Long, srcPurposefulAccountId: PurposefulAccountId, purposefulAccountTransfer: PurposefulAccountTransfer, secondPurposefulAccountTransfer: PurposefulAccountTransfer) {
        val srcBooking = bookPrepaid(eventId, srcPurposefulAccountId, -(purposefulAccountTransfer.amount + secondPurposefulAccountTransfer.amount))
        val trgFirstBooking = bookPrepaid(eventId, purposefulAccountTransfer.trgPurposefulAccountId, purposefulAccountTransfer.amount)
        val trgSecondBooking = bookPrepaid(eventId, secondPurposefulAccountTransfer.trgPurposefulAccountId, secondPurposefulAccountTransfer.amount)
    }

您只需要对所有命令进行分类即可确保没有循环依赖关系(假设T()接受vararg(:

fun threeLegBookPrepaid(eventId: Long, ...) {
   val txs = sortedMapOf(
      srcAccountId  to bookPrepaid(eventId, srcAccountId , ...),
      trg1AccountId to bookPrepaid(eventId, trg1AccountId, ...),
      trg2AccountId to bookPrepaid(eventId, trg2AccountId, ...)
   )
   .map { it.component2() }
   .toTypedArray()
   T(*txs)
}

这可以轻松地将其推广到任意数量的帐户。

最新更新