Возможно ли для базы данных блокировать параллельные обращения к таблицам в потоках Scala? - PullRequest
0 голосов
/ 18 февраля 2020

В моем приложении Scala я делаю несколько тем. В каждом потоке я записываю разные данные из массива в одну таблицу PostgreSQL. Я заметил, что некоторые потоки не записывают данные в таблицу PostgreSQL. Однако в журналах приложений ошибок нет. Возможно ли для базы данных блокировать параллельные обращения к таблицам? Что может быть причиной такого поведения?

MainApp. scala:

val postgreSQL = new PostgreSQL(configurations)

val semaphore = new Semaphore(5)

for (item <- array) {
    semaphore.acquire()

    val thread = new Thread(new CustomThread(postgreSQL, semaphore, item))

    thread.start()
}

CustomThread. scala:

import java.util.concurrent.Semaphore
import java.util.UUID.randomUUID
import utils.PostgreSQL

class CustomThread(postgreSQL: PostgreSQL, semaphore: Semaphore, item: Item) extends Runnable {
    override def run(): Unit = {
        try {
            // Create the unique filename.
            val filename: String = randomUUID().toString

            // Write to the database the filename of the item.
            postgreSQL.changeItemFilename(filename, item.id)

            // Change the status type of the item.
            postgreSQL.changeItemStatusType(3, request.id)
        } catch {
            case e: Throwable =>
                e.printStackTrace()
        } finally {
            semaphore.release()
        }
    }
}

PostgreSQL. scala:

package utils

import java.sql.{Connection, DriverManager, PreparedStatement, ResultSet}
import java.util.Properties

class PostgreSQL(configurations: Map[String, String]) {
  val host: String = postgreSQLConfigurations("postgresql.host")
  val port: String = postgreSQLConfigurations("postgresql.port")
  val user: String = postgreSQLConfigurations("postgresql.user")
  val password: String = postgreSQLConfigurations("postgresql.password")
  val db: String = postgreSQLConfigurations("postgresql.db")
  val url: String = "jdbc:postgresql://" + host + ":" + port + "/" + db
  val driver: String = "org.postgresql.Driver"

  val properties = new Properties()

  val connection: Connection = getConnection

  var statement: PreparedStatement = _

  def getConnection: Connection = {
    properties.setProperty("user", user)
    properties.setProperty("password", password)

    var connection: Connection = null

    try {
      Class.forName(driver)
      connection = DriverManager.getConnection(url, properties)
    } catch {
      case e:Exception =>
        e.printStackTrace()
    }

    connection
  }

  def changeItemFilename(filename: String, id: Int): Unit = {
    try {
      statement = connection.prepareStatement("UPDATE REPORTS SET FILE_NAME = ? WHERE ID = ?;", ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY)
      statement.setString(1, filename)
      statement.setInt(2, id)
      statement.execute()
    } catch {
      case e: Exception =>
        e.printStackTrace()
    }
  }
}

1 Ответ

1 голос
/ 18 февраля 2020

Просто для вашего интереса, по умолчанию JDB C равен синхронный . Это означает, что он блокирует ваш поток, пока операция не будет выполнена с указанным c соединением. Это означает, что если вы попытаетесь выполнить несколько действий на одном соединении одновременно, действия будут выполняться последовательно.

Подробнее об этом: https://dzone.com/articles/myth-asynchronous-jdbc

Это первая и наиболее вероятная причина. Вторая возможная причина - база данных блокирует изменения действий над ячейками таблицы, которые обновляются другой транзакцией, насколько точно - зависит от уровень изоляции .

https://www.sqlservercentral.com/articles/isolation-levels-in-sql-server

Это вторая вероятная причина.

Последнее, но не менее важное: не обязательно использовать голые нити в Scala. Для параллельного / асинхронного программирования было разработано много библиотек, таких как cats-effect , monix , zio , и существуют специальные библиотеки для доступа к базе данных, использующие такие библиотеки, как пятно или дуб ie. Лучше использовать их, чем голые нити по многим причинам.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...