Spring Transactional 中先写后读

问题描述 投票:0回答:1

Spring 的 Transactional 在先写后读时的行为是什么?

假设我有一个用

@Transactional
注解的方法,它所做的第一件事就是修改一个对象。然后,我读了那个对象。获取的对象是旧的、未修改的版本还是修改后的版本?或者,它认为这是脏读吗?

@Transactional
public Item writeThenRead(Item something) {
    myDao.writeSomething(something);
    Item fetched = myDao.readThatThing(something.getId());

    return fetched;
}
spring spring-annotations
1个回答
0
投票

据我了解,您感兴趣的是,与

Item something
Item fetched

相比,对象的值是否相同

这句话是真的

但事实并非如此,它们没有分配相同的内存,因此它是一个不同的对象,但它仍然具有相同的值或来自您的问题“修改版本”。无论您更新并保存或调用

writeSomething
,该方法之后的值都会反映在获取的 Item 中,只是内存位置会有所不同。

您可以在调试器中检查,您将在调试器中看到类似的内容

something = {Item@5555} "Item{id=14,name='UpdatedName'}"
fetched = {Item@9504} "Item{id=14,name='UpdatedName'}"

值将是最新的,但内存位置不会指向同一个对象。 请记住,在您跨过“

writeSomething
”后,您的更改将出现在数据库中,因此当您的代码到达“
readThatThing
”时,它将从您的数据库读取数据,而不是您的内存。

测试的最佳方法是简单地更新数据并在

readThatThing
方法上进行调试,进入数据库,通过查询更改数据,然后跨过
readThatThing
并允许调用它,您将看到数据是从数据库中调用的。

现在对于基于意见的“脏读”,如果它满足您检查值是否已更新并传播到数据库的要求,那么这是完全好的方法,甚至是一个很好的测试用例。

© www.soinside.com 2019 - 2024. All rights reserved.