I’ve been working on a new web app since October. The backend is a GraphQL API on top of a database schema. Each entry point unpacks the request and then calls a function that queries or mutates the database. There are some complex mutations—ones where there might be updates, inserts, and deletions that all need to succeed or fail together.
I know that I’m supposed to do this with transactions, but I was also using an ORM that I’m not very familiar with, and wanted to make progress quickly. I decided to pay lip-service to transactions, wrap some functions in them to indicate to myself that I needed to think about them, but mostly just ignore them. I would never not do transactions in a production app, but for this, it made sense.
After MVP, a month or so ago, I’ve just been adding minor things while my partner onboards some trial users. Eventually, I tried to implement a feature where the API call could result in many inserts and deletions, and I could see in tests that I could cause this to fail in ways that corrupted the data.
So, I had to stop, learn how to do transactions in this ORM, and then implement them in my data code. It took a few hours, and now the debt is paid off.
I do this kind of short-term borrowing/paying of debt all of the time. I am borrowing to keep myself in flow. I try to keep the debt top-of-mind by making it very evident in the code. It’s like using a credit card where you pay it off inside the grace period.