Slick 3 Transactions with Logic in Scala

I have a question about Slick 3 and Transactions

I read the documentation

http://slick.typesafe.com/doc/3.1.0/dbio.html

and other Slick 3 transaction issues

Slick 3 Transactions

Performing actions without a database in a transaction in Slick 3

But they didn’t help me.

I need to read some values ​​from the database, run some logic in Scala, and then change the database depending on the result. I want the whole operation to be atomic.

My code looks something like this:

database.run(TableQuery[X].filter(blah).result).map { x => database.run { if( someLogicNotInSQL(x) ) TableQuery[Y].insert(someFoo) else TableQuery[Y].insert(someBah) } } 

How to get the value of a query, start some logic in Scala, and then start another action (for example, insert) as one atomic transaction.

Thanks Peter

+5
source share
1 answer

To accomplish this in a transaction, you will need to create one action containing your queries and logic. Then run this action with the transaction.

Change your example:

 import scala.concurrent.ExecutionContext.Implicits.global val action = tableQuery.filter(blah).result.flatMap { x => if (someLogicNotInSql(x)) tableQuery.insert(someFoo) else tableQuery.insert(someBah) } 

flatMap requires an argument from x to a DBIO[T] . He will consistently group the two actions, allowing the second to use the result of the first.

To complete this collaborative action, you will need an execution context. (Because your calculation, if (someLogicNotInSql ... , will have to run in some thread somewhere, and not in the context of the internal context).

You can combine this combined action into a transaction and just call run once:

  val future = database.run(action.transactionally) 
+4
source

Source: https://habr.com/ru/post/1234548/


All Articles