簡體   English   中英

在PGConnection.getNotifications中獲取大小

[英]Fetch size in PGConnection.getNotifications

當表更新時,我的postgresql數據庫中的函數會發送通知。 我正在通過scalikejdbc輪詢該postgresql數據庫,以獲取所有通知,然后對它們進行一些處理。 該過程被解釋這里 典型的反應式系統會更新sql表。 我從java.sql.Connection獲得PGConnection。 而且,在那之后,我以這種方式收到通知:

val notifications = Option(pgConnection.getNotifications).getOrElse(Array[PGNotification]())

我試圖通過將獲取大小設置為1000並禁用自動提交功能,以1000個為大塊來獲取通知。 但是提取大小屬性將被忽略。

有什么想法可以做到嗎? 我不想在通知數據集中的一張地圖中處理成千上萬的通知。

pgConnection.getNotifications.size可能很大,因此,此代碼無法很好地擴展。

謝謝!!!

為了更好地擴展,請考慮使用postgresql-asyncAkka Streams :前者是一個可以異步獲取PostgreSQL通知的庫,而前者是提供反壓的Reactive Streams實現(這將消除對分頁的需求)。 例如:

import akka.actor._
import akka.stream._
import akka.stream.scaladsl._

import com.github.mauricio.async.db.postgresql.PostgreSQLConnection
import com.github.mauricio.async.db.postgresql.util.URLParser

import scala.concurrent.duration._
import scala.concurrent.Await

class DbActor(implicit materializer: ActorMaterializer) extends Actor with ActorLogging {
  private implicit val ec = context.system.dispatcher

  val queue =  
    Source.queue[String](Int.MaxValue, OverflowStrategy.backpressure)
      .to(Sink.foreach(println))
      .run()

  val configuration = URLParser.parse("jdbc:postgresql://localhost:5233/my_db?user=dbuser&password=pwd")
  val connection = new PostgreSQLConnection(configuration)
  Await.result(connection.connect, 5 seconds)

  connection.sendQuery("LISTEN my_channel")
  connection.registerNotifyListener { message =>
    val msg = message.payload
    log.debug("Sending the payload: {}", msg)
    self ! msg
  }

  def receive = {
    case payload: String =>
      queue.offer(payload).pipeTo(self)
    case QueueOfferResult.Dropped =>
      log.warning("Dropped a message.")
    case QueueOfferResult.Enqueued =>
      log.debug("Enqueued a message.")
    case QueueOfferResult.Failure(t) =>
      log.error("Stream failed: {}", t.getMessage)
    case QueueOfferResult.QueueClosed =>
      log.debug("Stream closed.")
  }
}

上面的代碼僅在發生時從PostgreSQL打印通知。 您可以將Sink.foreach(println)替換為另一個Sink 要運行它:

import akka.actor._
import akka.stream.ActorMaterializer

object Example extends App {
  implicit val system = ActorSystem()
  implicit val materializer = ActorMaterializer()
  system.actorOf(Props(classOf[DbActor], materializer))
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM