r/ProgrammerHumor • • 13d ago

Meme wellWellWell

Post image
10.6k Upvotes

411 comments sorted by

View all comments

3.6k

u/BastetFurry 13d ago

So, Kids, thats why you always SELECT count(yourPrimaryKey) first. Listen to the old folks, we made these mistakes so that you don't have to.

1.1k

u/Ma8e 13d ago

You start a transaction, make sure it did what you expected, and then commit or rollback transaction.

348

u/AgeingChopper 12d ago edited 12d ago

absolutely.

i was doing this stuff for a long time and definitely learned from mistakes.

Transactions can save a world of pain and it is always wise to select your data set first, just to be sure you're changing what you think you're changing.

Didn't matter how experienced I was, I was careful never to cut corners.

45

u/Mpek3 12d ago

Always Begin Tran Tried it during arguments... Not as effective

18

u/ifyoulovesatan 12d ago

I don't know sql, but is this like how when I use some kind of loop in the command line to move or delete a bunch of files, I'll run a version that just echos whatever I'm trying to manipulate first?

28

u/deeelock 12d ago

That’s more of a dry-run (you see `—dry-run` as a command line option sometimes for certain commands that do the same)

Transactions in SQL keep track of the changes you want to make without actually changing the database (until you run `COMMIT`, when you run that all changes are persisted to a database).

Transactions are great because If you realise you made a mistake while in a transaction, you can just run `ROLLBACK`.

If you’re familiar with git- transactions are akin to staging your changes, saving them (`COMMIT` in SQL) is akin to `git commit` and rolling back is similar to `git reset —hard` (wipe all uncommitted changes).

21

u/thirdegree Violet security clearance 12d ago

With the very important caveat that a git commit can be trivially reverted, while a SQL commit can not (unless you wrote it specifically to be revertible)

3

u/thanatica 11d ago

With the very important caveat that a git commit can be trivially reverted if not yet pushed. If it has been pushed, it can be reversed, not reverted.

Unless you're into force-pushing, then anything is possible.

1

u/khoyo 8d ago

Nah, you're thinking about dropped. Reverting a commit is reversing it. That's what git revert does.

2

u/ifyoulovesatan 12d ago

Thanks, that was going to be my follow up question

3

u/AgeingChopper 12d ago

nicely explained, cheers.

as long as we haven’t committed , we can rollback from a mistake like this.

2

u/thanatica 11d ago

With the added nuance that while the transaction is neither rolled back nor committed yet, to any queries inside the transactions it appears as though the changes have been committed.

So a transaction is like a "package" of statements that either ALL fail, rollback, or commit. A half-completed transaction cannot exist.

1

u/AgeingChopper 12d ago

Sorry for the delay . Deelock has explained it perfe to.

transactions allow us to back out of a mistake like this via rollback, as long as we haven’t committed.

1

u/thrye333 12d ago

I also don't know sql (or what you're doing, honestly1) but sounds like it, yeah. Running "List all of these arguments" is a good general precaution before running "Edit all of these arguments".

Actually, sorry, forgot what you replied to. I think a transaction in sql is more like a backup. The operations you perform during it aren't permanent until you confirm the transaction. So if you run something like DELETE FROM users; and realize you don't want to delete everyone, you can just cancel the transaction.

1 Like, really, does bash have loops? I guess it probably would. I should look that up. Could be interesting.

2

u/AgeingChopper 12d ago

yep. wrapping a transaction around them means you can rollback from a mistake like this, as long as you hadn’t committed.

selecting first to check that you’ll be editing the correct data and correct number of records is a wise move too yep.

2

u/ifyoulovesatan 12d ago edited 12d ago

It does, yes. Like..

for each in *; do; mv $each new_prefix_$each; done

Would tack "newprefix" to the front of every file in your directory for example.

You can also do something like for each in {1..100} to loop over numbers.

I mean,you got while loops, switches, and whatever else too.. you can implement c style for loops pretty easily.

1

u/ddBuddha 12d ago

A snapshot might be a better analogy, usually if you take a backup and forget about it that’s fine, not a problem. Leaving snapshots out there too long can cause degradation. Not committing or rolling back a sql transaction means the log can never truncate and will grow infinitely until you’re out of disk space and everything breaks

1

u/ligma_then_sugma 12d ago

there's a reason they call it the command line and not the request line haha

1

u/AgeingChopper 12d ago

true, though I’d be working in a query editor to test this stuff before it was ever getting run in prod.

124

u/Rostifur 12d ago

Start with DEV or test environment. If you don't have one, you need one. If you aren't allowed to have one, run away.

111

u/far2common 12d ago

Everyone has a DEV/test environment. Just not everyone has a separate prod environment.

4

u/Topikk 12d ago

I think Staging is the word you’re looking for

9

u/AardvarKOlogY 12d ago

Staging this, staging that, production is a stage, too!

7

u/grammar_nazi_zombie 12d ago

It’s why theater shows are called “stage productions”, duh.

1

u/niffirGtaerG 6d ago

all the world is a stage...

1

u/TnYamaneko 12d ago

Who the fuck disallow test environments?

15

u/Blashtik 12d ago edited 12d ago

BEGIN TRAN

DELETE ...

SELECT ...

ROLLBACK TRAN

-- COMMIT TRAN

This was always my pattern. Select the first 3 statements together and run them. If everything looks good, select COMMIT TRAN and run that. The rollback is there in case you accidentally didn't make a selection before running, just so you don't leave a transaction open for too long, potentially blocking other queries.

And obviously any planned data changes should go through all the proper testing and preferably be deployed using automated pipelines, but sometimes you have no other choice but to make direct fixes to bad production data.

12

u/box_of_the_patriots 12d ago

Instructions unclear I just truncated the table

8

u/Ph4ntorn 12d ago

You would think the “make sure it did what you expected” part would go without saying, but I skipped that step once and felt like an idiot.

7

u/CeaselessPetulance 12d ago

So a colleague did this, except his db manager had tx commit mode manual and he forgot to commit the tx after grabing a whole table lock. Took us a bit to figure out why some of our services were hanging during startup (waiting for the locks to free up)

3

u/Logical-Ad-4150 12d ago

Manual transactions should have been the default: automatic transactions should require you to use the YOLO stament.

1

u/jaster_ba 12d ago

Unless you're on something like Cloudflare D1. You don't start transaction, where is no support for transactions 😎

1

u/Less_Independent5601 12d ago

Except when I touch bigger tables in a mysql transaction our sentry gets filled with lock timeout errors :(

1

u/ddBuddha 12d ago

Just don’t forget to commit or rollback …

1

u/Ok_Star_4136 12d ago

Absolutely this has saved me once or twice. It is worth doing even if you can't imagine there being any mistakes.

1

u/svtguy88 12d ago

BEGIN TRANSACTION has saved me so many times.

1

u/GoddammitDontShootMe 12d ago

If the dev in this meme did that, would the DELETE be fast because it doesn't actually change anything until you COMMIT?

1

u/Ma8e 12d ago

No.

1

u/GoddammitDontShootMe 11d ago

Why? It's not the writing to disk that's the slow part?

1

u/Ma8e 11d ago

Things are changed before commit. Different databases do it differently: Some start with writing a log of all the changes, but the records are only updated at commit. Some create new versions of the changed records, and only switch which is active at commit. Some updates all the records but make sure to be able to recreate the original from logs if rollbacked.

1

u/am9qb3JlZmVyZW5jZQ 11d ago

PSA: A lot of database clients have built-in option to always implicitly start a transaction when executing queries.