Seeking thoughts on advantages of the Repo.transact pattern vs disadvantages I’ve read about Ecto.Multi

I wrote Repo.transact after seeing a lot of production code along the lines of what’s written in that excellent blog post by @tomkonidas.

The value proposition of Repo.transact is that control flow features such as passing data around, branching, early exit, can be implemented with standard Elixir features, such as variables, functions, and the with expression. The transactional logic is less special, and it doesn’t rely on some implicit behaviour of a function from some library.

Combined with the provable fact that the transact code is shorter (often significantly), even in such simple example as in that blog post, I have no doubt that the transact version is simpler and clearer.

That’s not to say that Multi is universally bad. The ability to provide each db operation as data is definitely interesting, and could be useful in the cases where the transactional steps need to be assembled dynamically (perhaps provided by the client code). But in the vast majority of cases I’ve encountered, I find the multi code needlessly difficult to read. This is true even in simple cases, and it becomes progressively worse if the transactional logic is more involved (e.g. if it requires branching early on in the transaction).

Hence, I strongly prefer transact, and it’s what I advise using in most situations.

25 Likes