Spring Transactional无法读取更新的值

时间:2016-04-19 15:25:34

标签: java spring transactions spring-data spring-transactions

我正在使用Spring并遵循junit-method:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:TestProject-spring-test.xml" })
@Transactional
public abstract class BaseTest {
[...]

    @Test
    public void testSaveLoadedObject() {
        SubTestModel st = modelService.load(subTestPk);

        st.setSimpleObject("testString");

        modelService.save(st);

        //now reload the object to ensure that everything has been saved correctly
        st = modelService.load(st.getId());
        s+= "\n#3 afterLoad:   " + st.getSimpleObject();

        //fails:
        Assert.assertTrue(st.getSimpleObject().equals("testString"));
    }
}

ModelService-方法:

@Autowired
private JdbcTemplate db;

@Override
@Transactional(propagation = Propagation.REQUIRED)
public void save(final ItemModel model, String newValue) {
    db.update("UPDATE table SET column=? WHERE id=?", new Object[] { newValue, model.getId() });
}

@Override
public <T extends AbstractItemModel> T load(final int id) {
    ...  
    DAO.loadValue(...)
}

DAO-方法:     @Autowired     private JdbcTemplate db;

@Override
public <T> T loadValue(final AbstractItemModel model, final String columnName) {
        final String sql = "SELECT column FROM table WHERE id=" + model.getId();

    Object plain = db.queryForObject(sql, new RowMapper<Object>() {
        @Override
        public Object mapRow(ResultSet r, int rowNum) throws SQLException {
            return r.getObject(columnName);
        }
    });

    return plain;

}

发生以下情况:

原值: enter image description here

新值存储在数据库中(在mysql中设置“SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED”时可见)。

getSimpleObject-DB in DB =“testString” enter image description here

*但是当调用load方法时,它会获得“old”(=保存前的值)值*

调试器中的getSimpleObject-Value =“simpleObjectValue”

为什么加载方法无法读取最近保存的值(在同一个事务和方法中)?

您看到它不会创建新事务。甚至在整个测试方法中使用“@Transaction(isolation = READ_UNCOMMITTED)”设置隔离级别也无济于事

任何人都可以解开这个谜团吗?

提前致谢!

1 个答案:

答案 0 :(得分:0)

在save方法上将传播更改为REQUIRES_NEW(在数据库上提交更改并打开新事务)。

或者甚至更好,在保存测试后添加flush调用(这样做更好,因为您不会更改代码只是为了使其适应您的集成测试)。