试图理解数据库事务是如何在Spring和数据库中实现的.我一直在编写很多查询,并使用了@Transactional个查询,但我从未真正try 过考虑数据库级别上发生的事情.

于是,我开始浏览hereherehere.

假设我们有这段代码:

@Service
public class ReservationService {
    private static final int SEAT_LIMIT = 50;
    private SeatsRepository seatsRepository;

    @Transactional
    public String reservate(User user){

        int currentSeatsReservations = seatsRepository.getCurrentSeatsReservations();
        if (SEAT_LIMIT - currentSeatsReservations >= 1){
            //make new seat reservation
            seatsRepository.addNewSeatReservation(System.currentTimeMillis(), user.getId());
            return "Congrats! You just made your reservation";
        }
        return "All seats are already booked";

    }
    @Repository
    interface SeatsRepository{
        @Query(value = "SELECT COUNT(id) as CURRENT_TOTAL_SEATS_TAKEN FROM seats;", nativeQuery = true)
        int getCurrentSeatsReservations();
        @Query(value = "INSERT INTO seats(timestamp, user_id) VALUES (:timestamp, :userId);", nativeQuery = true)
        void addNewSeatReservation(long timestamp, int userId);
    }

}

我确实知道MySQL的默认隔离是REPEATABLE_READ.但这将如何配合下面的情况,就像在图像中一样?

enter image description here

让我们想象一下,我们有一个简单的单程航班要填满座位.我们说50个座位吧.订座实行先到先得的原则.通过在一个简单的seats表中插入新行来进行预订.

图中可以看到这张桌子.

这种情况有可能出现吗?我知道在数据库级别上一切都发生得很快,但是假设左边的事务(T1)由于某种原因比右边的事务(T2)慢.由于我们处于REPEATABLE_READ隔离级别,因此不会发生DIRESS_READ、NON_REPEATABLE_READS和PHATOM_READS(作为并发问题).

另外,任何关于这一主题的好书或Udemy课程的推荐都将不胜感激.不过,我还是个初学者.

推荐答案

START TRANSACTION;
SELECT ... FOR UPDATE;
...
UPDATE ...;
COMMIT;

请注意FOR UPDATE这个数字.它增加了额外的锁定,以防止出现您所描述的问题.

(我认为TRANSACTION_ISOLATION_MODE对于您的示例并不重要.)

Mysql相关问答推荐

约会时的意外行为

返回包含某一列的分组最大值的行,说明列中的重复值

MySQL中如何对字符串进行算术运算?

查询优化并提高性能

避免多个SQL查询的重构代码

在带有 D.I 的 .NET AWS Lambda 中使用 MySql.Data

数据导入和默认目标架构空列表. (Mysql 工作台 8)

我在连接到 mysql 的 node js 中收到错误消息发送到客户端后无法设置标头

创建 mySQL BEFORE/AFTER UPDATE 触发器

为生日创建 MySQL 索引

如何从具有第一行列值的表中 Select 客户的最新记录

Django中的MYSQL查询等效

是否可以在一个查询中将字符串附加到许多匹配的行

在 MySQL 中 Select COUNT of MAX

重新加载 .env 变量而不重新启动服务器(Laravel 5,共享主机)

仅在 MYSQL DATEDIFF 中显示小时数

使用 mysql 处理非常大的数据

表被指定了两次,既作为更新的目标,又作为 mysql 中数据的单独源

在 MySQL Workbench 中导出超过 1000 条记录的查询结果

按 COUNT(*) 过滤?