Prevent deadlock in internalAddToPlayerShards by introducing internalGetShardTypeShards
This commit is contained in:
2 files changed
+22
-8
No files matched your search
@@ -35,7 +35,8 @@ class DiamondBankAPIKotlin {
|
||||
|
||||
return transactionLock.withLockSuspend(uuid) {
|
||||
val player = Bukkit.getPlayer(uuid) ?: Bukkit.getOfflinePlayer(uuid)
|
||||
if (player !is Player && !player.hasPlayedBefore()) return@withLockSuspend Result.failure(InvalidPlayerException())
|
||||
if (player !is Player && !player.hasPlayedBefore())
|
||||
return@withLockSuspend Result.failure(InvalidPlayerException())
|
||||
|
||||
balanceManager.addToBankShards(uuid, shards.toLong()).getOrElse {
|
||||
handleError(it)
|
||||
@@ -68,7 +69,8 @@ class DiamondBankAPIKotlin {
|
||||
|
||||
return transactionLock.withLockSuspend(uuid) {
|
||||
val player = Bukkit.getPlayer(uuid) ?: Bukkit.getOfflinePlayer(uuid)
|
||||
if (player !is Player && !player.hasPlayedBefore()) return@withLockSuspend Result.failure(InvalidPlayerException())
|
||||
if (player !is Player && !player.hasPlayedBefore())
|
||||
return@withLockSuspend Result.failure(InvalidPlayerException())
|
||||
|
||||
balanceManager.subtractFromBankShards(uuid, shards.toLong()).getOrElse {
|
||||
if (it is InsufficientBalanceException) return@withLockSuspend Result.failure(it)
|
||||
@@ -161,7 +163,8 @@ class DiamondBankAPIKotlin {
|
||||
|
||||
return transactionLock.withLockSuspend(uuid) {
|
||||
val player = Bukkit.getOfflinePlayer(uuid)
|
||||
if (player !is Player && !player.hasPlayedBefore()) return@withLockSuspend Result.failure(InvalidPlayerException())
|
||||
if (player !is Player && !player.hasPlayedBefore())
|
||||
return@withLockSuspend Result.failure(InvalidPlayerException())
|
||||
|
||||
player.uniqueId
|
||||
.withInventoryLockSuspend {
|
||||
@@ -220,10 +223,12 @@ class DiamondBankAPIKotlin {
|
||||
|
||||
return transactionLock.withLockSuspend(senderUuid) {
|
||||
val sender = Bukkit.getPlayer(senderUuid) ?: Bukkit.getOfflinePlayer(senderUuid)
|
||||
if (sender !is Player && !sender.hasPlayedBefore()) return@withLockSuspend Result.failure(InvalidPlayerException())
|
||||
if (sender !is Player && !sender.hasPlayedBefore())
|
||||
return@withLockSuspend Result.failure(InvalidPlayerException())
|
||||
|
||||
val receiver = Bukkit.getPlayer(receiverUuid) ?: Bukkit.getOfflinePlayer(receiverUuid)
|
||||
if (receiver !is Player && !receiver.hasPlayedBefore()) return@withLockSuspend Result.failure(InvalidPlayerException())
|
||||
if (receiver !is Player && !receiver.hasPlayedBefore())
|
||||
return@withLockSuspend Result.failure(InvalidPlayerException())
|
||||
|
||||
sender.uniqueId
|
||||
.withInventoryLockSuspend {
|
||||
|
||||
@@ -139,7 +139,7 @@ internal class PostgreSQL private constructor() {
|
||||
.await()
|
||||
|
||||
if (result.rows.isEmpty()) {
|
||||
val shards = getShardTypeShards(uuid, type).getOrElse { throw it }
|
||||
val shards = internalGetShardTypeShards(uuid, type, conn).getOrElse { throw it }
|
||||
throw InsufficientBalanceException(shards)
|
||||
}
|
||||
val row = result.rows[0]
|
||||
@@ -271,12 +271,21 @@ internal class PostgreSQL private constructor() {
|
||||
}
|
||||
|
||||
suspend fun getShardTypeShards(uuid: UUID, type: ShardType): Result<Long> {
|
||||
var shards: Long?
|
||||
try {
|
||||
val connection = pool.asSuspending.connect()
|
||||
|
||||
return internalGetShardTypeShards(uuid, type, connection)
|
||||
} catch (e: Exception) {
|
||||
plugin.logger.severe(e.toString())
|
||||
return Result.failure(DatabaseException(e.message ?: "Database exception"))
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun internalGetShardTypeShards(uuid: UUID, type: ShardType, conn: Connection): Result<Long> {
|
||||
var shards: Long?
|
||||
try {
|
||||
val result =
|
||||
connection
|
||||
conn
|
||||
.inTransaction { conn ->
|
||||
conn.sendPreparedStatement(
|
||||
"SELECT ${type.string} FROM diamond WHERE uuid = ? LIMIT 1",
|
||||
|
||||
Reference in new issue
Block a user