0Pricing
Scala for Backend Engineering & Functional Programming · Ders

İşlemleri Birleştirme

Etkileri güvenle birleştirin.

İşlemleri Birleştirme, CoddyKit'te ücretsiz bir Scala for Backend Engineering & Functional Programming dersidir. Bu, 4 dersinin 4. dersidir. Aşağıdan dersin tamamını ücretsiz okuyabilir, sonra tarayıcıda yerleşik kod editörü ve 7/24 yapay zeka koçu ile uygulamalı olarak pratik yapabilirsin. Bu, Scala for Backend Engineering & Functional Programming öğrenme yolunun bir parçasıdır ve ilerlemeniz web ve CoddyKit uygulaması arasında senkronize olur. Scala for Backend Engineering & Functional Programming kursu toplamda 4 dersten oluşur.

ConnectionIO Bir Monad'dır

Doobie'nin asıl gücü, ConnectionIO'nun bir monad olmasıdır. flatMap veya for-comprehension kullanarak birçok ifadeyi tek bir büyük programda birleştirebilirsiniz.

Bu şekilde sıraladığınız her şey, aynı bağlantı üzerinde tek bir işlem içinde çalışır.

import doobie.implicits._

val program: ConnectionIO[Long] =
  for {
    id <- insertUser("Ada")
    _  <- insertProfile(id)
  } yield id

Her transact için Bir İşlem

Kaç ifade birleştirirseniz birleştirin, .transact çağrıldığında tüm ConnectionIO tek bir işleme dönüşür.

Herhangi bir adım başarısız olursa Transactor'ın stratejisi her şeyi geri alır; tüm adımlar başarılı olursa sonunda tek seferde onaylar.

val io: IO[Long] = program.transact(xa)

Atomik Çok İfadeli Yazma İşlemleri

Birleştirilen ifadeler aynı işlemi paylaştığından atomiklik kendiliğinden sağlanır. Bir hesaptan borç düşüp başka bir hesaba alacak ekleyen transfer ya tamamen gerçekleşir ya da hiç gerçekleşmez.

İkinci güncelleme hata verirse kısmi bir durum oluşmaz.

def transfer(from: Long, to: Long, cents: Int) =
  for {
    _ <- sql"update acct set bal = bal - $cents where id = $from".update.run
    _ <- sql"update acct set bal = bal + $cents where id = $to".update.run
  } yield ()

Hataları Yükseltme ve Ele Alma

ConnectionIO bir MonadError örneğine sahiptir; bu nedenle bir işlemi durdurup geri almayı tetiklemek için raiseError kullanabilirsiniz.

Kurtarmak için handleErrorWith da kullanabilirsiniz; ancak işlem geri alınmadıkça kurtarmanın önceki ifadeleri kendiliğinden geri almadığını unutmayın.

import cats.syntax.all._
import doobie.free.connection.{raiseError, pure}

def debit(id: Long, c: Int): ConnectionIO[Unit] =
  sql"update acct set bal = bal - $c where id = $id".update.run.flatMap {
    case 1 => pure(())
    case _ => raiseError(new RuntimeException("no such account"))
  }

Bir İşlemde Koşullu Mantık

Bu yapı yalnızca bir monad olduğundan normal Scala denetim akışı çalışır. Bir satırı okuyabilir, değerine göre dallanabilir ve sonucu atomik olarak yazabilirsiniz.

Bu, iş kurallarını ve kalıcılaştırmayı tek ve tutarlı bir birimde tutar.

for {
  bal <- sql"select bal from acct where id = $id".query[Int].unique
  _   <- if (bal >= amt)
           sql"update acct set bal = bal - $amt where id = $id".update.run
         else raiseError(new RuntimeException("insufficient funds"))
} yield ()

Kısmi Geri Alma için Kayıt Noktaları

Daha ayrıntılı denetim için Doobie, JDBC Savepoint değerlerini FC (serbest bağlantı) cebiri aracılığıyla sunar. Tüm işlemi iptal etmeden bir kayıt noktasına geri dönebilirsiniz.

Bu, tek bir dış işlem içinde deneme ve alternatif yol kalıplarını mümkün kılar.

import doobie.free.{connection => FC}

val withSp =
  for {
    sp <- FC.setSavepoint
    _  <- riskyWrite.handleErrorWith(_ => FC.rollback(sp))
  } yield ()

Sorguları ve Yazma İşlemlerini Birleştirme

Okuma ve yazma işlemleri aynı programda serbestçe karıştırılabilir. Mevcut durumu seçebilir, Scala'da bir değişiklik hesaplayabilir ve bunları tek bir bağlantı üzerinde kalıcılaştırabilirsiniz.

Okuma işlemi, aynı işlem içinde daha önce yapılmış ve henüz onaylanmamış değişiklikleri görür.

for {
  v <- sql"select stock from items where id = $id".query[Int].unique
  _ <- sql"update items set stock = ${v - 1} where id = $id".update.run
  n <- sql"select stock from items where id = $id".query[Int].unique
} yield n

traverse ile Programları Yeniden Kullanma

Programlar değer olduğundan, cats'in traverse işleviyle aynı programı bir liste üzerinde çalıştırabilir ve bunları tek bir işlem içinde sıralayabilirsiniz.

Tüm eklemeler birlikte onaylanır veya hiçbiri onaylanmaz.

import cats.syntax.all._

def saveAll(names: List[String]): ConnectionIO[List[Long]] =
  names.traverse(insertUser)

Yalıtım Düzeyleri

İşlemin yalıtım düzeyini, çalışmanızı gerçekleştirmeden önce bağlantı cebirini kullanarak bir programın içinde ayarlayabilirsiniz.

SERIALIZABLE gibi daha katı düzeyler tutarsızlıkları önler; ancak veritabanının çakışan işlemleri iptal etmesine neden olabilir. Bu durumda işlemi yeniden denemeniz gerekir.

import doobie.free.{connection => FC}
import java.sql.Connection

val serializable =
  FC.setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE) *> program

Serileştirme Hatalarında Yeniden Deneme

Yeniden denemeler işlemde değil, etki katmanında yapılmalıdır. .transact sonrasında bir IO elde edersiniz ve serileştirme hatasında işlemin tamamını yeniden deneyebilirsiniz.

Her yeniden deneme yeni ve bağımsız bir işlemdir.

def runWithRetry(io: IO[Unit], n: Int): IO[Unit] =
  io.handleErrorWith {
    case _ if n > 0 => runWithRetry(io, n - 1)
    case e          => IO.raiseError(e)
  }

İşlemleri Kısa Tutma

Yalnızca atomik olması gereken çalışmayı tek bir ConnectionIO içinde birleştirin. Harici çağrıları (HTTP, yavaş CPU çalışmaları) bir işlem içinde gerçekleştirmeyin; bunlar bağlantıyı ve kilitleri meşgul tutar.

Mümkünse okuyun, hesaplamayı dışarıda yapın ve ardından sıkı kapsamlı bir işlem içinde yazın.

// good: gather input first, then one short transactional write
val write: ConnectionIO[Int] =
  sql"update users set name = $name where id = $id".update.run

Hızlı Denetim

İşlem sınırlarını değerlendirin.

Özet

ConnectionIO bir monaddır; bu nedenle for-comprehension ifadeleri, ifadeleri her .transact çağrısında tek bir atomik işlemde birleştirir. Hatalar her şeyi geri alır; raiseError ise işlemi kasıtlı olarak durdurur.

Kısmi geri alma için kayıt noktalarını kullanın, yalıtım düzeylerini program içinde ayarlayın, serileştirme hatalarında etki katmanında yeniden deneyin ve işlemleri kısa tutun.

Sıkça Sorulan Sorular

“İşlemleri Birleştirme” dersi ücretsiz mi?

Evet — “İşlemleri Birleştirme” dersin tüm metni burada web'de ücretsiz olarak okunabilir. Etkileşimli olarak pratik yapmak (yerleşik kod editörü ve 7/24 yapay zeka koçu) ve Scala for Backend Engineering & Functional Programming kursunun geri kalanını açmak için CoddyKit PRO'ya yükselt. Scala for Backend Engineering & Functional Programming kursu toplamda 4 dersten oluşur.

“İşlemleri Birleştirme” dersinde ne öğreneceğim?

Etkileri güvenle birleştirin. Scala for Backend Engineering & Functional Programming ile uygulamalı kodu tarayıcıda doğrudan çalıştırarak pratik yaparsın ve 7/24 yapay zeka koçu dersi çalışırken sorularını yanıtlar.

Scala for Backend Engineering & Functional Programming öğrenmeye başlamak için deneyim gerekli mi?

Önceden deneyim gerekmez. CoddyKit'te Scala for Backend Engineering & Functional Programming, başlangıçtan ileri seviyeye kadar yapılandırıldığı için buradan başlayabilir veya başından başlayıp kendi hızında ilerleme yapabilirsin. Bu, 4 dersinin 4. dersidir.

“İşlemleri Birleştirme” dersi ne kadar sürer?

Çoğu CoddyKit dersi yaklaşık 5–10 dakika sürer. Her biri kısa ve etkileşimli olduğu için sabit ilerleme yaparsın ve web ile uygulama arasında tam olarak bıraktığın yerden devam edebilirsin.

Bu Scala for Backend Engineering & Functional Programming dersinde kod yazıp çalıştırabilir miyim?

Evet. Her Scala for Backend Engineering & Functional Programming dersi yerleşik bir kod editörü içerir, bu sayede tarayıcıda gerçek kod yazıp çalıştırabilir ve anlık yapay zeka geri bildirimi alırsın — yerel kurulum gerekli değildir.

Bu kursun tüm dersleri

  1. Transactor ile Bağlanma
  2. Sorguları Çalıştırma
  3. Ekleme ve Güncelleme
  4. İşlemleri Birleştirme
← Scala for Backend Engineering & Functional Programming Sayfasına Dön