Scala for Backend Engineering & Functional Programming · Leçon

Se connecter avec un transacteur

Configurez l’accès à la base de données.

Leçon 1 sur 413 étapes

Se connecter avec un transacteur est une leçon Scala for Backend Engineering & Functional Programming gratuite sur CoddyKit. Ceci est la leçon 1 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage Scala for Backend Engineering & Functional Programming, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours Scala for Backend Engineering & Functional Programming comprend 4 leçons au total.

Qu'est-ce qu'un Transactor ?

Doobie est une couche JDBC fonctionnelle pure pour Scala. Un Transactor[F] fait le lien entre les programmes purs de Doobie et une connexion réelle à la base de données.

Un Transactor sait acquérir une connexion JDBC Connection, exécuter votre programme dans une transaction et libérer les ressources en toute sécurité.

Il est paramétré par un type d'effet F[_] tel que cats.effect.IO.

import doobie._
import cats.effect.IO

val xa: Transactor[IO] = ???

Le programme ConnectionIO

Les requêtes Doobie sont des valeurs de type ConnectionIO[A]. Elles décrivent un calcul qui nécessite une connexion JDBC, mais ne s'exécutent pas encore.

Vous construisez ces programmes de manière pure, puis vous les transmettez à un Transactor pour les exécuter. Rien n'accède à la base de données tant que vous ne l'avez pas lancé.

import doobie.implicits._

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

DriverManagerTransactor

Le Transactor le plus simple est Transactor.fromDriverManager. Il ouvre une connexion entièrement nouvelle pour chaque transaction à l'aide du DriverManager de JDBC.

Il nécessite le nom de la classe du pilote, l'URL JDBC, le nom d'utilisateur et le mot de passe. Il convient aux tests et aux scripts, mais ne dispose d'aucun pool de connexions.

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

Exécution d'un programme

Pour exécuter un ConnectionIO, vous appelez .transact(xa). Cela produit un F[A], ici un IO[A].

Le Transactor enveloppe le programme dans une transaction : il valide en cas de succès et annule en cas d'échec, en libérant la connexion dans les deux cas.

import doobie.implicits._

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

Mise en pool avec HikariCP

En production, vous avez besoin d'un pool de connexions. Doobie fournit HikariTransactor, basé sur HikariCP.

Il est créé comme une Resource, afin que le pool soit arrêté proprement. Vous transmettez également un contexte d'exécution pour les opérations JDBC bloquantes.

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
  )

Pourquoi une Resource ?

Un Transactor utilisant un pool possède un état à longue durée de vie : des connexions ouvertes et des threads en arrière-plan. Resource[F, A] garantit que l'acquisition et la libération sont toujours associées, même en cas d'erreur ou d'annulation.

En général, vous construisez le Transactor une seule fois au démarrage et le réutilisez pendant toute la durée de vie de l'application.

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

Le pool connectEC

HikariCP a besoin d'un ExecutionContext pour attendre les connexions du pool. Doobie fournit ExecutionContexts.fixedThreadPool à cette fin, lui-même sous forme de Resource.

Le fait de le séparer de votre pool de calcul empêche l'acquisition bloquante de connexions de priver de ressources les tâches liées au CPU.

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

Configuration d'un DataSource existant

Si vous disposez déjà d'un javax.sql.DataSource configuré (par exemple une instance Hikari optimisée), enveloppez-le directement avec Transactor.fromDataSource.

C'est courant lorsqu'un framework gère le pool et que vous voulez seulement que Doobie l'utilise.

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

Test rapide de la connexion

Une vérification d'état simple consiste à exécuter select 1 via le Transactor. Si elle renvoie un résultat, votre pilote, votre URL et vos identifiants fonctionnent tous.

C'est une bonne première étape avant de mettre en place de véritables requêtes.

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

// check.unsafeRunSync() == 1

Fonctionnement interne du Transactor : stratégie

Un Transactor est construit à partir d'interpréteurs et d'une Strategy. La Strategy contrôle ce qui se passe autour de chaque transaction : before, after, oops (en cas d'erreur) et always.

La stratégie par défaut désactive la validation automatique, valide après un succès, annule en cas d'erreur et ferme toujours la connexion.

import doobie.util.transactor.Strategy

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

Journalisation et observabilité

Doobie peut journaliser chaque instruction, ses arguments et sa durée d'exécution. Les versions modernes associent un LogHandler[F] à chaque requête plutôt qu'à chaque Transactor.

C'est extrêmement utile pour repérer les requêtes lentes et vérifier la liaison des paramètres en production.

import doobie.util.log._

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

Vérification rapide

Vérifiez votre compréhension des Transactors.

Récapitulatif

Un Transactor[F] relie les programmes purs ConnectionIO à une base de données réelle. fromDriverManager convient aux tests ; HikariTransactor et fromDataSource conviennent à la production grâce à la mise en pool.

Construisez les Transactors utilisant un pool comme une Resource, exécutez les programmes avec .transact(xa) et laissez la Strategy par défaut gérer la validation, l'annulation et le nettoyage.

Gratuit pour commencer

Apprends Scala avec un tuteur IA — gratuit

Écris et exécute du vrai code dans ton navigateur, obtiens de l'aide instantanée d'un tuteur IA disponible 24h/24, et reprends là où tu t'es arrêté sur le web ou dans l'app.

Cours
39
Leçons
143

Questions Fréquemment Posées

La leçon « Se connecter avec un transacteur » est-elle gratuite ?

Oui — le texte complet de « Se connecter avec un transacteur » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours Scala for Backend Engineering & Functional Programming, passe à CoddyKit PRO. Le cours Scala for Backend Engineering & Functional Programming comprend 4 leçons au total.

Qu'est-ce que j'apprendrai dans « Se connecter avec un transacteur » ?

Configurez l’accès à la base de données. Tu pratiques Scala for Backend Engineering & Functional Programming avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.

Dois-je avoir de l'expérience pour commencer Scala for Backend Engineering & Functional Programming ?

Aucune expérience préalable n'est requise. Scala for Backend Engineering & Functional Programming sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 1 sur 4.

Combien de temps prend la leçon « Se connecter avec un transacteur » ?

La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.

Peux-tu écrire et exécuter du code dans cette leçon Scala for Backend Engineering & Functional Programming ?

Oui. Chaque leçon Scala for Backend Engineering & Functional Programming inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.

Toutes les leçons de ce cours

  1. Se connecter avec un transacteur
  2. Exécuter des requêtes
  3. Insertions et mises à jour
  4. Composer des transactions
← Retour à Scala for Backend Engineering & Functional Programming