0Pricing
Scala for Backend Engineering & Functional Programming · درس

الاتصال باستخدام Transactor

أعدّ الوصول إلى قاعدة البيانات

الاتصال باستخدام Transactor درس مجاني في Scala for Backend Engineering & Functional Programming على CoddyKit. هذا هو الدرس 1 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في Scala for Backend Engineering & Functional Programming، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة Scala for Backend Engineering & Functional Programming 4 دروس في المجموع.

ما هو Transactor؟

Doobie هي طبقة JDBC وظيفية بالكامل لـ Scala. يمثّل Transactor[F] الجسر بين برامج Doobie النقية واتصال قاعدة بيانات حقيقي.

يعرف Transactor كيفية اقتناء اتصال JDBC من نوع Connection، وتشغيل برنامجك داخل معاملة، وتحرير الموارد بأمان.

ويُحدَّد بمعامل نوع التأثير F[_]، مثل cats.effect.IO.

import doobie._
import cats.effect.IO

val xa: Transactor[IO] = ???

برنامج ConnectionIO

استعلامات Doobie هي قيم من النوع ConnectionIO[A]. وهي تصف عملية تحتاج إلى اتصال JDBC، لكنها لا تُشغّل بعد.

تبني هذه البرامج بصورة نقية، ثم تسلّمها إلى Transactor لتنفيذها. ولا يلامس أي شيء قاعدة البيانات حتى تشغّل البرنامج.

import doobie.implicits._

val program: ConnectionIO[Int] =
  sql"select 42".query[Int].unique

DriverManagerTransactor

أبسط Transactor هو Transactor.fromDriverManager. فهو يفتح اتصالًا جديدًا تمامًا لكل معاملة باستخدام DriverManager الخاص بـ JDBC.

ويحتاج إلى اسم فئة برنامج التشغيل، وعنوان JDBC، واسم المستخدم، وكلمة المرور. وهو مناسب للاختبارات والبرامج النصية، لكنه لا يوفر تجميعًا للاتصالات.

val xa = Transactor.fromDriverManager[IO](
  driver = "org.postgresql.Driver",
  url = "jdbc:postgresql://localhost:5432/app",
  user = "postgres",
  password = "secret",
  logHandler = None
)

تشغيل برنامج

لتنفيذ ConnectionIO، استدعِ .transact(xa). وينتج عن ذلك F[A]، وهنا يكون IO[A].

يغلّف Transactor البرنامج داخل معاملة: يثبت التغييرات عند النجاح، ويتراجع عنها عند الفشل، ويحرر الاتصال في كلتا الحالتين.

import doobie.implicits._

val result: IO[Int] =
  sql"select 42".query[Int].unique.transact(xa)

التجميع باستخدام HikariCP

في بيئة الإنتاج تحتاج إلى تجمع اتصالات. توفر Doobie النوع HikariTransactor المدعوم من HikariCP.

ويُنشأ باعتباره Resource كي يُغلق التجمع بطريقة سليمة. كما تمرر سياق تنفيذ لعمليات JDBC الحاجبة.

import doobie.hikari.HikariTransactor
import cats.effect.IO

val xaRes: Resource[IO, HikariTransactor[IO]] =
  HikariTransactor.newHikariTransactor[IO](
    "org.postgresql.Driver",
    "jdbc:postgresql://localhost/app",
    "postgres", "secret",
    connectEC
  )

لماذا Resource؟

يمتلك Transactor المجمّع حالة طويلة الأمد: اتصالات مفتوحة ومؤشرات ترابط تعمل في الخلفية. يضمن Resource[F, A] اقتران الاقتناء بالتحرير حتى عند حدوث أخطاء أو إلغاء.

عادةً ما تبني Transactor مرة واحدة عند بدء التشغيل، ثم تعيد استخدامه طوال عمر التطبيق.

xaRes.use { xa =>
  program.transact(xa)
}

تجمع connectEC

يحتاج HikariCP إلى ExecutionContext لانتظار الاتصالات من التجمع. توفر Doobie لهذا الغرض ExecutionContexts.fixedThreadPool، وهو مورد بحد ذاته.

يمنع فصل هذا التجمع عن تجمع الحسابات حجب اقتناء الاتصالات من استنفاد العمل المرتبط بالمعالج.

import doobie.util.ExecutionContexts

val poolRes =
  for {
    ec <- ExecutionContexts.fixedThreadPool[IO](8)
    xa <- HikariTransactor.newHikariTransactor[IO](
            "org.postgresql.Driver", url, user, pass, ec)
  } yield xa

ضبط DataSource موجود

إذا كان لديك javax.sql.DataSource مضبوط مسبقًا، مثل مثيل Hikari مُحسَّن، فغلّفه مباشرةً باستخدام Transactor.fromDataSource.

يشيع ذلك عندما يتولى إطار عمل إدارة التجمع، ولا تريد من Doobie سوى استخدامه.

val xa = Transactor.fromDataSource[IO](
  dataSource = myDataSource,
  connectEC = connectEC
)

اختبار أولي للاتصال

تتمثل إحدى فحوصات الصحة البسيطة في تشغيل select 1 عبر Transactor. فإذا أعاد نتيجة، فهذا يعني أن برنامج التشغيل والعنوان وبيانات الاعتماد تعمل جميعًا.

هذه خطوة أولى جيدة قبل توصيل الاستعلامات الفعلية.

val check: IO[Int] =
  sql"select 1".query[Int].unique.transact(xa)

// check.unsafeRunSync() == 1

الأجزاء الداخلية لـ Transactor: Strategy

يُبنى Transactor من مفسرات ومن Strategy. وتتحكم Strategy فيما يحدث حول كل معاملة: before وafter وoops (عند الخطأ) وalways.

توقف الاستراتيجية الافتراضية التثبيت التلقائي، وتثبت التغييرات بعد النجاح، وتتراجع عنها عند الخطأ، وتغلق الاتصال دائمًا.

import doobie.util.transactor.Strategy

val noCommit = xa.copy(
  strategy0 = Strategy.default.copy(after = doobie.free.connection.unit)
)

التسجيل وقابلية الرصد

يمكن لـ Doobie تسجيل كل عبارة، ومعاملاتها، وتوقيتها. وتربط الإصدارات الحديثة LogHandler[F] بكل استعلام بدلًا من ربطه بكل Transactor.

وهذا لا يقدّر بثمن لاكتشاف الاستعلامات البطيئة والتحقق من ربط المعاملات في بيئة الإنتاج.

import doobie.util.log._

val handler: LogHandler[IO] = (ev: LogEvent) =>
  IO.println(ev.sql)

تحقق سريع

اختبر فهمك لـ Transactors.

مراجعة

يربط Transactor[F] برامج ConnectionIO النقية بقاعدة بيانات حقيقية. يناسب fromDriverManager الاختبارات، بينما يناسب كل من HikariTransactor وfromDataSource بيئة الإنتاج عبر التجميع.

ابنِ Transactors المجمّعة باعتبارها Resource، وشغّل البرامج باستخدام .transact(xa)، ودع Strategy الافتراضية تتولى التثبيت والتراجع والتنظيف.

الأسئلة الشائعة

هل درس «الاتصال باستخدام Transactor» مجاني؟

نعم — نص درس «الاتصال باستخدام Transactor» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة Scala for Backend Engineering & Functional Programming، انتقل إلى CoddyKit PRO. تتضمن دورة Scala for Backend Engineering & Functional Programming 4 دروس في المجموع.

ماذا ستتعلم في «الاتصال باستخدام Transactor»؟

أعدّ الوصول إلى قاعدة البيانات تتمرن على Scala for Backend Engineering & Functional Programming مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.

هل أحتاج إلى خبرة سابقة لأبدأ Scala for Backend Engineering & Functional Programming؟

لا تُشترط خبرة سابقة. Scala for Backend Engineering & Functional Programming على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 1 من أصل 4.

كم من الوقت يستغرق درس «الاتصال باستخدام Transactor»؟

معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.

هل يمكنني كتابة وتشغيل أكواد في درس Scala for Backend Engineering & Functional Programming هذا؟

نعم. كل درس في Scala for Backend Engineering & Functional Programming يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.

جميع الدروس في هذه الدورة

  1. الاتصال باستخدام Transactor
  2. تشغيل الاستعلامات
  3. عمليات الإدراج والتحديث
  4. تركيب المعاملات
← العودة إلى Scala for Backend Engineering & Functional Programming