# How nubank operates without traditional transaction features like commit/rollback?

**URL:** <https://forum.datomic.com/t/how-nubank-operates-without-traditional-transaction-features-like-commit-rollback/1680>\
**Category:** General\
**Created:** [November 10, 2020, 4:38pm UTC](https://forum.datomic.com/t/how-nubank-operates-without-traditional-transaction-features-like-commit-rollback/1680 "2020-11-10T16:38:09Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![nikolayandr](https://sea2.discourse-cdn.com/flex016/user_avatar/forum.datomic.com/nikolayandr/32/375_2.png) [@nikolayandr](https://forum.datomic.com/u/nikolayandr)\
**Post date:** [November 10, 2020, 4:38pm UTC](https://forum.datomic.com/t/how-nubank-operates-without-traditional-transaction-features-like-commit-rollback/1680/1 "2020-11-10T16:38:09Z")

</div>

Since the last news [https://www.cognitect.com/blog/2020/07/23/Cognitect-Joins-Nubank](https://www.cognitect.com/blog/2020/07/23/Cognitect-Joins-Nubank) I believe it can be asked here:

Transactions with ability to commit/rollback are something like “must have” for financial systems(at least my expierence says it), how nubank operates without such feature wich is not provided in datomic due to its nature?

---

<div class="post-metadata">

**Author:** ![stu](https://sea2.discourse-cdn.com/flex016/user_avatar/forum.datomic.com/stu/32/11_2.png) [@stu](https://forum.datomic.com/u/stu)\
**Post date:** [November 11, 2020, 10:24pm UTC](https://forum.datomic.com/t/how-nubank-operates-without-traditional-transaction-features-like-commit-rollback/1680/2 "2020-11-11T22:24:10Z")

</div>

Datomic provides a set of capabilities for ensuring data integrity that far surpasses basic commit/rollback:

1. Datomic has [ACID transactions](https://docs.datomic.com/cloud/transactions/acid.html).
2. Datomic automatically enforces [uniqueness](https://docs.datomic.com/cloud/schema/schema-reference.html#db-unique) and [cardinality](https://docs.datomic.com/cloud/schema/schema-reference.html#db-cardinality) constraints.
3. Datomic allows you to specify arbitrary predicates of both [attributes](https://docs.datomic.com/cloud/schema/schema-reference.html#attribute-predicates) and [entities](https://docs.datomic.com/cloud/schema/schema-reference.html#entity-specs).
4. Datomic allows you to write [arbitrary code, running inside a transaction](https://docs.datomic.com/cloud/transactions/transaction-functions.html#custom), to perform arbitrarily complex validations.

Do you have an example of something you are trying to do?

---

<div class="post-metadata">

**Author:** ![nikolayandr](https://sea2.discourse-cdn.com/flex016/user_avatar/forum.datomic.com/nikolayandr/32/375_2.png) [@nikolayandr](https://forum.datomic.com/u/nikolayandr)\
**Post date:** [November 12, 2020, 8:12am UTC](https://forum.datomic.com/t/how-nubank-operates-without-traditional-transaction-features-like-commit-rollback/1680/3 "2020-11-12T08:12:19Z")

</div>

Actually I came up to the same case described [here](https://forum.datomic.com/t/traditional-transactions-commit-multiple-changes-at-once/565) .

My current solution is the same, transact statements using **with** each time accumulating statements, each next call is done to the db returned from **with**. In the case of success all collected changes are pushed to real database in the single call, but some questions arise:

1. What if some statements(previously executed step by step on memory db returned from **with** ) call transaction functions which might depend on result from the previously transacted statements. In such case collected statements can’t be called at once on real database
2. If some statement creates entity and the next one uses id of that entity then such statements can’t be executed at once.
3. If first statement creates a entity and the next one retracts the entity

P.S. Maybe the most right solution in this case is to develop in a way which do not need rollback but maximally use features which are provided by datomic to keep data constraints

P.P.S Why I asked about nubank because usually logic of bank operations is not so simple and can be described as:

```
try {
0. Open transaction
1. do this
2. put some data here
3. change data there
4. Commit
catch (Exception e) {
  rollback transaction
}
```

---

<div class="post-metadata">

**Author:** ![dazld](https://sea2.discourse-cdn.com/flex016/user_avatar/forum.datomic.com/dazld/32/370_2.png) [@dazld](https://forum.datomic.com/u/dazld)\
**Post date:** [November 14, 2020, 11:09am UTC](https://forum.datomic.com/t/how-nubank-operates-without-traditional-transaction-features-like-commit-rollback/1680/4 "2020-11-14T11:09:25Z")

</div>

I suppose the fundamental difference here is that a transaction is an atomic thing already - it either makes sense as a whole against a value of db, or it doesn’t. Consequently, the job of the “do this”, “put some data here”, “put some data there” is to accumulate speculative changes in the form of data for a transaction.

Your `with` approach is arguably redundant here, as even if your `with` calls have made sense against that value of the db locally, there’s no guarantee they will when you _really_ transact them. It feels like a postgres-ism (or similar) that doesn’t really make sense in a datomic world.

For example, and as I guess you know, postgres has things like isolation levels, distributed locks etc to allow imperative sequences of calls to be treated as a reversible transaction (with a cost!), but that just doesn’t equate here.

About your point 2, creating and referencing entities in a transaction, this is why tempids exist, no?

On point 3, wouldn’t that throw due to conflicts in the transaction? That said, having to worry about asserting and retracting the same entity in the same transaction feels like something isn’t quite right in your data flow, and could be elided before submitting a transaction, or be an invariant, for example.
