Je veux pouvoir entourer un bloc de code avec une transaction. Le code d'appel doit être aussi simple que cela:Comment rendre le code appelant agnostique de paramètre implicite passé sous le capot?
transactional {
save("something")
}
Je pensais à faire fonctionner transactional
comme ceci:
def transactional(block: => Unit): Unit = {
implicit val conn: Connection = ???
conn.begin()
try {
block
conn.commit()
} catch {
case ex: Exception =>
conn.rollback()
throw ex
} finally {
conn.close()
}
}
Maintenant, la méthode save
aura besoin de faire quelque chose avec la connexion, mais je veux pour rendre le code appelant agnostique de cela (voir ci-dessus). Je naïvement mis en œuvre comme ceci:
def save(operation: String)(implicit conn: Connection): Unit = {
println(s"saving $operation using $conn")
}
Bien sûr, je reçois une erreur de compilation, que la connexion ne peut être trouvé. Quelle partie me manque pour connecter la connexion de la fonction transactional
à la fonction save
?
Merci, la version modifiée me permet de laisser la connexion hors du code d'appel. Cela améliore également la réponse de Tzach Zohar en ce sens que je peux toujours enrouler du code autour de la fonction de sauvegarde, et cela fonctionnera toujours. J'accepterai cette réponse pour cette raison. Si l'emballage n'est pas nécessaire, sa réponse est légèrement plus simple. –