In this post, we will explore various database locking mechanisms using a real-world example: an airline seat booking system. We’ll simulate how different transaction isolation levels and locks can be applied in a concurrent environment. We will use Go for implementing our business logic and PostgreSQL or YugabyteDB for the database. This system simulates multiple users concurrently booking seats on the same flight.
Why Database Locking?
Database locking is critical in multi-transaction environments where concurrent access to shared data occurs. The primary purpose is to maintain data integrity and consistency, ensuring that operations like seat booking don’t result in race conditions or conflicts.
Types of Locks:
- Pessimistic Locking: A lock is acquired before proceeding with a transaction. This ensures that no other transaction can modify or read the locked data until the lock is released.
- Optimistic Locking: Rather than locking data upfront, a check is made at the end of a transaction to ensure that no conflicts occurred during the transaction.
In this post, we will focus on pessimistic locking.
Example: Airline Seat Booking System
In our airline seat booking system:
- Each flight has 120 seats.
- Multiple users concurrently attempt to book seats for the same flight.
The system is designed to handle concurrent booking attempts, where each user tries to book the first available seat.
Database Locking Mechanisms Used
We will explore four cases with different database locking strategies:
- No Locking: No lock is acquired on rows, which can lead to race conditions.
- FOR UPDATE: A row is locked before modifying, preventing other transactions from modifying or reading it.
- FOR UPDATE NOWAIT: A row is locked, but if it’s already locked by another transaction, an error is thrown immediately.
- FOR UPDATE SKIP LOCKED: Skips any locked rows and continues with available rows.
Let’s walk through these cases.
1. Case 0: No Locking
In this case, we fetch the first available seat without applying any locking. This can result in race conditions, where multiple users might attempt to book the same seat concurrently.
// Case 0: No Locking (direct selection)
row := txn.QueryRow(`
SELECT id, name, trip_id, user_id
FROM seats
WHERE trip_id = 1 AND user_id IS NULL
ORDER BY id
LIMIT 1`)
Outcome: Multiple users might book the same seat, causing conflicts and data corruption.
2. Case 1: Locking with FOR UPDATE
In this case, we acquire a lock on the row using FOR UPDATE. This prevents other transactions from accessing or modifying the seat until the lock is released.
// Case 1: FOR UPDATE (blocks other transactions)
row := txn.QueryRow(`
SELECT id, name, trip_id, user_id
FROM seats
WHERE trip_id = 1 AND user_id IS NULL
ORDER BY id
LIMIT 1 FOR UPDATE`)
Outcome: Other transactions trying to book the same seat will be blocked until the current transaction completes, ensuring consistency.
3. Case 2: Locking with FOR UPDATE NOWAIT
Here, we use FOR UPDATE NOWAIT. This locks the row, but if it’s already locked by another transaction, an error is thrown immediately, and the transaction fails.
// Case 2: FOR UPDATE NOWAIT (fails immediately if row is locked)
row := txn.QueryRow(`
SELECT id, name, trip_id, user_id
FROM seats
WHERE trip_id = 1 AND user_id IS NULL
ORDER BY id
LIMIT 1 FOR UPDATE NOWAIT`)
Outcome: If a seat is locked by another transaction, an error is thrown, and the booking process stops for the current user.
4. Case 3: Locking with FOR UPDATE SKIP LOCKED
In this case, we use FOR UPDATE SKIP LOCKED, which skips any locked rows and processes the next available row. This ensures that the system continues processing other seats even when some are locked by other transactions.
// Case 3: FOR UPDATE SKIP LOCKED (skips locked rows)
row := txn.QueryRow(`
SELECT id, name, trip_id, user_id
FROM seats
WHERE trip_id = 1 AND user_id IS NULL
ORDER BY id
LIMIT 1 FOR UPDATE SKIP LOCKED`)
Outcome: Locked rows are skipped, and the system continues processing other available seats, ensuring high throughput and minimal contention.
Full Implementation: queries.go
Here’s a sample implementation of the Book function that simulates these locking mechanisms. You can uncomment the locking case you wish to simulate:
package data
import (
"database/sql"
"fmt"
"log"
)
// Book assigns the first available seat to a user.
func Book(db *sql.DB, user User) (*Seat, error) {
txn, err := db.Begin()
if err != nil {
return nil, fmt.Errorf("failed to start transaction: %w", err)
}
defer txn.Rollback()
// Uncomment the case you want to run:
// Case 0: No locking (direct selection)
row := txn.QueryRow(`
SELECT id, name, trip_id, user_id
FROM seats
WHERE trip_id = 1 AND user_id IS NULL
ORDER BY id
LIMIT 1`)
// Case 1: FOR UPDATE
// row := txn.QueryRow(`
// SELECT id, name, trip_id, user_id
// FROM seats
// WHERE trip_id = 1 AND user_id IS NULL
// ORDER BY id
// LIMIT 1 FOR UPDATE`)
// Case 2: FOR UPDATE NOWAIT
// row := txn.QueryRow(`
// SELECT id, name, trip_id, user_id
// FROM seats
// WHERE trip_id = 1 AND user_id IS NULL
// ORDER BY id
// LIMIT 1 FOR UPDATE NOWAIT`)
// Case 3: FOR UPDATE SKIP LOCKED
// row := txn.QueryRow(`
// SELECT id, name, trip_id, user_id
// FROM seats
// WHERE trip_id = 1 AND user_id IS NULL
// ORDER BY id
// LIMIT 1 FOR UPDATE SKIP LOCKED`)
var seat Seat
err = row.Scan(&seat.ID, &seat.Name, &seat.TripID, &seat.UserID)
if err != nil {
return nil, fmt.Errorf("no seat available: %w", err)
}
// Update the seat to assign it to the user
_, err = txn.Exec(`UPDATE seats SET user_id = $1 WHERE id = $2`, user.ID, seat.ID)
if err != nil {
return nil, fmt.Errorf("failed to assign seat: %w", err)
}
if err := txn.Commit(); err != nil {
return nil, fmt.Errorf("failed to commit transaction: %w", err)
}
return &seat, nil
}
Conclusion
Different database locking mechanisms provide varying levels of concurrency control. Depending on the business requirements and concurrency level, you can choose the most appropriate locking strategy:
- No locking might be suitable in low-concurrency environments where performance is critical.
- FOR UPDATE ensures data consistency but might block other transactions.
- FOR UPDATE NOWAIT provides fast feedback for locked rows.
- FOR UPDATE SKIP LOCKED ensures high throughput by skipping locked rows.
Try implementing this in your next concurrent system and experiment with different cases to see which one fits your needs!
Reference:
https://docs.yugabyte.com/preview/explore/transactions/explicit-locking
https://github.com/DevelopersCoffee/database-concepts-in-action/tree/main/airlinecheckin


When I originally commented I clicked the -Notify me when new comments are added- checkbox and now each time a comment is added I get four emails with the same comment. Is there any way you can remove me from that service? Thanks!
I needed to send you the tiny note just to say thanks a lot over again on the exceptional techniques you have documented on this site. It is really seriously generous with people like you to make easily precisely what many individuals could possibly have distributed for an ebook to help make some dough for their own end, specifically considering the fact that you might well have tried it if you ever considered necessary. These pointers as well worked to provide a easy way to fully grasp the rest have similar passion similar to my personal own to know very much more related to this problem. I am certain there are many more pleasurable opportunities up front for people who browse through your blog post.
Simply desire to say your article is as astounding. The clearness in your post is simply nice and i can assume you are an expert on this subject. Well with your permission let me to grab your feed to keep up to date with forthcoming post. Thanks a million and please carry on the rewarding work.
Приветствуем вас на нашем веб-сайте!
Здесь вы найдёте всё необходимое для успешного
управления своими финансами. Мы предлагаем широкий спектр финансовых продуктов, которые помогут вам достичь
ваших целей и обеспечить стабильность в будущем.
В нашем ассортименте представлены различные виды банковских продуктов, инвестиции,
страхование, кредиты и многое другое.
Мы постоянно обновляем нашу базу данных, чтобы
вы всегда были в курсе последних тенденций
и инноваций на финансовом рынке.
Наши специалисты помогут вам выбрать наиболее подходящий продукт, учитывая ваши индивидуальные потребности и предпочтения.
Мы предоставляем консультации и рекомендации, чтобы вы могли
принять обоснованное решение и избежать возможных рисков.
Не упустите возможность воспользоваться нашими услугами и
откройте для себя мир финансовых возможностей!
Заходите на наш сайт, ознакомьтесь с каталогом продуктов и начните свой путь к финансовой
стабильности прямо сейчас!
займ для многодетных семей
Wonderful blog! I found it while surfing around on Yahoo News. Do you have any suggestions on how to get listed in Yahoo News? I’ve been trying for a while but I never seem to get there! Thanks
Great post, Uday! Your explanation of database locking with real-world airline seat booking examples is super practical. The breakdown of FOR UPDATE strategies really helps understand concurrency control. For SaaS teams building complex systems like this, clear communication is key—Creamy Animation’s SaaS video production is a great resource to simplify and showcase such concepts. Thanks for the valuable insights!
I think this is one of the most important information for me. And i’m glad reading your article. But should remark on some general things, The website style is wonderful, the articles is really great : D. Good job, cheers
Hurrah, that’s what I was seeking for, what a stuff!
existing here at this website, thanks admin of this web page.
Greetings from California! I’m bored at work so I
decided to check out your website on my iphone during lunch break.
I really like the information you present here and can’t wait to take
a look when I get home. I’m amazed at how quick your blog loaded on my mobile ..
I’m not even using WIFI, just 3G .. Anyhow, great site!
Spot on with this write-up, I honestly believe this website needs much more attention. I’ll probably be returning
to see more, thanks for the information!
https://panzerschiffadmiralgrafspee.de/
I have been exploring for a bit for any high quality articles or
weblog posts in this kind of space . Exploring in Yahoo I ultimately stumbled upon this web site.
Reading this info So i’m glad to express that I’ve an incredibly just right uncanny
feeling I found out just what I needed. I such a lot undoubtedly will make certain to do not
forget this web site and give it a look on a relentless basis.
I was suggested this web site by my cousin. I am not sure
whether this post is written by him as nobody else know such
detailed about my problem. You are amazing! Thanks!
An outstanding share! I have just forwarded this onto a coworker who was
doing a little homework on this. And he in fact ordered me dinner due to the fact that I
found it for him… lol. So allow me to reword this….
Thank YOU for the meal!! But yeah, thanks for spending some time to talk about this topic here on your web site.
I’ve read a few just right stuff here. Certainly value bookmarking for
revisiting. I surprise how a lot attempt you
place to create the sort of magnificent informative site.
Useful info. Lucky me I discovered your website by accident,
and I am shocked why this accident didn’t took place earlier!
I bookmarked it.
Thanks for your marvelous posting! I actually enjoyed
reading it, you happen to be a great author.I will ensure that
I bookmark your blog and definitely will come back later on. I want to encourage you to ultimately continue
your great posts, have a nice evening!
Hello, its good piece of writing concerning media print, we all
be familiar with media is a great source of facts.
Hey There. I found your blog using msn. This is a very well written article.
I will be sure to bookmark it and return to read more of your
useful information. Thanks for the post. I’ll definitely comeback.
Hey there! I know this is somewhat off topic but I was wondering if
you knew where I could locate a captcha plugin for my comment form?
I’m using the same blog platform as yours and I’m having difficulty finding one?
Thanks a lot!
I am regular reader, how are you everybody? This article posted at this
website is truly pleasant.
Hi there! I just wanted to ask if you ever have any trouble
with hackers? My last blog (wordpress) was hacked and I ended up losing several weeks of hard work
due to no data backup. Do you have any solutions to stop hackers?
Hello There. I found your blog using msn. This is a very well written article.
I’ll make sure to bookmark it and come back to
read more of your useful info. Thanks for the post. I’ll certainly return.
Useful information. Fortunate me I discovered your web site
by accident, and I am stunned why this accident did not happened earlier!
I bookmarked it.
Wonderful article! This is the kind of information that should be shared across the web.
Disgrace on the search engines for now not positioning this submit higher!
Come on over and visit my site . Thank you =)
Right here is the perfect blog for anybody who wants to understand
this topic. You understand a whole lot its almost hard to argue with
you (not that I really will need to…HaHa). You definitely put a brand new spin on a subject which has
been discussed for decades. Great stuff, just great!
If you are going for most excellent contents like
me, simply pay a visit this web page daily as it offers feature contents, thanks
Truly no matter if someone doesn’t understand after
that its up to other viewers that they will help,
so here it occurs.
My brother suggested I would possibly like this blog.
He was entirely right. This submit truly made my day. You can not consider simply how so much time I had spent for this info!
Thanks!
Can I just say what a relief to find somebody who truly knows what they are discussing over the internet.
You definitely realize how to bring a problem to light and make it important.
More people should check this out and understand this side of your story.
I was surprised you are not more popular since you most certainly possess the gift.
This is really interesting, You’re a very professional blogger.
I have joined your rss feed and sit up for searching for more of your
great post. Also, I’ve shared your web site in my social networks
Thanks for sharing your thoughts about . Regards
What’s up to every one, the contents present at this website are truly amazing for people experience,
well, keep up the nice work fellows.
I will right away grab your rss as I can’t find your e-mail subscription link or e-newsletter service.
Do you have any? Kindly let me understand so that I could subscribe.
Thanks.
Hello to all, how is all, I think every one is
getting more from this web site, and your views are good in support of
new people.
Post writing is also a fun, if you know afterward you can write or else it is difficult to write.
Today, I went to the beach with my kids. I found a sea shell and gave it to
my 4 year old daughter and said “You can hear the ocean if you put this to your ear.” She put the
shell to her ear and screamed. There was a hermit crab inside and
it pinched her ear. She never wants to go back! LoL I know this is totally
off topic but I had to tell someone!
I like the valuable information you provide in your articles.
I will bookmark your weblog and check again here regularly.
I’m quite certain I will learn many new stuff right here!
Good luck for the next!
Thanks for another wonderful article. The place else may anyone get that
kind of information in such an ideal method of writing?
I have a presentation next week, and I am at the search for
such info.
My coder is trying to persuade me to move to .net from PHP.
I have always disliked the idea because of the expenses.
But he’s tryiong none the less. I’ve been using WordPress
on a number of websites for about a year and am worried about switching to another platform.
I have heard excellent things about blogengine.net.
Is there a way I can import all my wordpress content into it?
Any help would be greatly appreciated!
If you would like to get a great deal from this paragraph then you have to apply these strategies to your won website.
Hello i am kavin, its my first occasion to commenting anyplace, when i read this
article i thought i could also create comment due to this
sensible paragraph.
What’s up to all, for the reason that I am truly eager of
reading this weblog’s post to be updated regularly. It includes pleasant information.
What’s up to every one, for the reason that I am actually keen of reading this web site’s post to be updated regularly.
It includes pleasant material.
Hi my friend! I wish to say that this post is awesome, nice written and include almost all vital infos.
I’d like to see more posts like this .
Good day I am so happy I found your webpage, I really found you by accident, while I
was browsing on Askjeeve for something else, Anyways I am
here now and would just like to say thank you for a incredible post and a all round interesting blog (I also love the theme/design), I don’t have time
to look over it all at the moment but I have bookmarked it and also included
your RSS feeds, so when I have time I will be back to read a
great deal more, Please do keep up the excellent work.
Piece of writing writing is also a fun, if you be
familiar with then you can write or else it is difficult to write.
Hi, I do think this is an excellent web site. I stumbledupon it
😉 I’m going to return once again since I bookmarked it. Money
and freedom is the greatest way to change, may you be rich and continue to help other people.
Very great post. I simply stumbled upon your weblog and wished to say that I’ve truly loved surfing around
your weblog posts. In any case I will be subscribing on your rss feed and I’m hoping you write once more very soon!