【问题标题】:Multiple Threads accessing the database: one with long transaction, one with short transactions多个线程访问数据库:一个长事务,一个短事务
【发布时间】:2011-05-28 02:21:26
【问题描述】:

假设我有一个桌面应用程序,可以作为一堆汽车的车库:

@Entity
public class Garage {
    private List<Car> cars = new ArrayList<Car>();
    ...
}

桌面应用程序有一个“模拟”按钮,它启动一个新线程并开始调用车库、汽车、车轮等上的方法。这个模拟可能需要长达 10 分钟才能运行。目前我有一个看起来像这样的类:

beginTransaction();
Garage garage = garageDao.findGarage(1);
List<Car> cars = garage.getCars();
for (Car car : cars) {
    // call methods on the car to lazily fetch other things like wheels...
}
commitTransaction();

这段代码只“读”,从不“写”

因此,上述操作可能需要很长时间,具体取决于汽车对服务的需求程度。当上述情况发生时,用户可以继续使用桌面应用程序工作。他们可以选择更改在上述交易中使用的汽车的颜色。

我的问题是,上述长交易是否会阻止汽车颜色的变化?即,在长事务完成之前,将阻止用户在桌面应用程序中更改汽车颜色的提交更改?

【问题讨论】:

  • 为什么需要事务才能读取?你在使用延迟获取吗?
  • “更新线程”必须是单个事务单元吗?还是没有更新?你说“这段代码只做‘读’,从不‘写’。然后——就像 saugata 所问的——你为什么需要交易?
  • 是的,在 Car 上调用的方法可能类似于 getWheels() 并且它们正在被延迟获取

标签: java database hibernate jpa


【解决方案1】:

为什么要这样做?默认情况下,您使用的是乐观事务,因此不会对正在读取的行应用锁定(除非您没有向我们展示一些 JPA2 lock() 调用)。然后事务的提交应检查记录的乐观版本(如果您定义了版本)并使用它来决定是否提交更改。

【讨论】:

    【解决方案2】:

    答案很可能取决于您使用的数据库,更重要的是使用哪种事务隔离级别。

    但答案通常是否定的:它们不应该阻塞(但正如我所说,取决于数据库和事务级别)。

    【讨论】:

      【解决方案3】:

      如上:

      通常,只读操作不应阻塞数据库中的写操作。 所以你的长读线程不应该阻塞短写操作。

      我认为可以为您的数据库配置隔离级别,并且写入的连接可能会被长读取语句阻塞,但这不是我所知道的任何数据库类型的默认设置。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多