gpt4 book ai didi

java - 防止并发访问 servlet 中的方法

转载 作者:行者123 更新时间:2023-11-30 05:50:42 25 4
gpt4 key购买 nike

我在 servlet 中有一个方法,可以在数据库中插入辅导预订。此方法有一个业务规则,用于检查该类(class)的导师在该日期和时间是否已经忙碌。代码看起来像这样:

class BookingService {
public void insert(Booking t) {
if(available(t.getTutor(), t.getDate(), t.getTime())) {
bookingDao.insert(t);
} else {
// reject
}
}
}

问题在于,多个用户可能会同时尝试在同一日期和时间预订同一位导师,并且没有什么可以阻止他们同时通过测试并插入预订。我尝试过使 insert() 同步并使用锁,但它不起作用。如何防止并发访问此方法?

最佳答案

使用同步并不足以解决此问题:

首先,您将对应用程序进行编码,以便一次只能部署一个实例。这不仅仅是在云中扩展。 IT 部门希望建立多个应用程序实例是很正常的,这样就不会出现单点故障(这样,万一托管一个实例的设备出现故障,应用程序仍然可用)。使用静态同步意味着锁不会超出一个应用程序类加载器,因此多个实例仍然可以以一种容易出错的方式交错其工作。

如果您在某个时候离开该项目,后来的维护人员可能不会意识到这个问题,并且可能会尝试以您不希望的方式部署应用程序。使用同步意味着你会留下一个让他们绊倒的地雷。

其次,使用同步块(synchronized block)会阻碍应用程序的并发性,因为一次只能有一个线程可以进行。

因此,您引入了瓶颈,同时切断了运营人员通过部署第二个实例来解决瓶颈的能力。这不是一个好的解决方案。

由于发布的代码没有显示事务所在位置的迹象,我猜测要么每个 DAO 创建自己的事务,要么您正在以自动提交模式进行连接。数据库提供事务来帮助解决此问题,并且由于该功能是在数据库中实现的,因此无论运行多少个应用程序实例,它都将起作用。

解决该问题并避免上述缺点的一个简单方法是将事务放在服务层,以便所有 DAO 调用都在同一事务中执行。您可以让服务层从池中检索数据库连接,启动事务,将连接传递给每个 DAO 方法调用,提交事务,然后将连接返回到池中。

关于java - 防止并发访问 servlet 中的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53952053/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com