2010-12-20 44 views
5

比方说,我有充当车库一堆汽车的桌面应用程序:多个线程访问数据库:一个长事务,一个短交易

@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(); 

此代码仅做“读”,也不会“写”

所以上面可以根据汽车如何迫切需要花费很长的时间一项服务。在发生上述情况时,用户可能会继续使用桌面应用程序工作。他们可能会选择更改上述交易中使用的汽车的颜色。

我的问题是,上述长交易是否会阻止汽车颜色的改变?即用户改变桌面应用程序中汽车的颜色将被阻止提交更改,直到长交易完成为止?

+0

为什么你需要一个交易来阅读?你在使用懒惰抓取? – saugata 2010-12-20 07:18:24

+0

'更新线程'必须是单个事务单元吗?还是没有更新?你说:“这段代码只是'读'而不写',然后 - 就像saugata问 - 为什么你需要交易? – 2010-12-20 07:36:04

+0

是的,在汽车上调用的方法可能类似于getWheels(),它们正在延迟获取 – digiarnie 2010-12-20 08:12:32

回答

4

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

+0

nope,无锁()调用 – digiarnie 2010-12-20 08:13:14

0

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

但是答案总的来说不是:他们不应该阻止(但正如我所说的,依赖于数据库和事务级别)。

0

如上:

通常情况下,只读操作不应该在一个数据库块写操作。 所以你的长读线程不应该阻塞短写操作。

我想可以为您的数据库和连接配置一个隔离级别,写入操作可以被长读取语句阻塞,但这不是我所知道的任何数据库类型的默认值。