Spring 的 Transactional 在先写后读时的行为是什么?
假设我有一个用
@Transactional
注解的方法,它所做的第一件事就是修改一个对象。然后,我读了那个对象。获取的对象是旧的、未修改的版本还是修改后的版本?或者,它认为这是脏读吗?
@Transactional
public Item writeThenRead(Item something) {
myDao.writeSomething(something);
Item fetched = myDao.readThatThing(something.getId());
return fetched;
}
据我了解,您感兴趣的是,与
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
并允许调用它,您将看到数据是从数据库中调用的。
现在对于基于意见的“脏读”,如果它满足您检查值是否已更新并传播到数据库的要求,那么这是完全好的方法,甚至是一个很好的测试用例。