Spring @Transactional注释表现得很奇怪

时间:2013-08-14 11:55:00

标签: spring hibernate jpa transactional

我有以下方法:

@Transactional
public void onEmailMessage() {

    this.departmentService.removeUserFromDepartments(user, depsids);
    this.departmentService.getDepartmentUsers(user.id); 
}

当我调用这个方法时,奇怪的是第一行:

  this.departmentService.removeUserFromDepartments(user, depsids);

被调用,但DB根本没有改变,用户仍然连接到deparment(多对多关系)

之后的方法:

   this.departmentService.getDepartmentUsers(user.id); 
调用

并返回连接到部门的用户,包括从第1行删除的用户。

当方法返回时 - 如果我检查数据库,我删除的用户实际上已从表中删除了!

我可以让查询返回实际的更新值吗?

3 个答案:

答案 0 :(得分:2)

这没什么奇怪的。您在同一事务中执行两个不同的查询。持久化上下文已更新,但尚未提交事务,并且在第一行完成后您无法看到更改。 Transaction是一组语句(在本例中是由您的两个方法创建的语句),它们在调用commit后执行。当整个(onEmailMessage)方法完成它的工作时,事务被提交并且您正在看到更改。

解决方案是:

将它们作为两个单独的交易。例如:

@Transactional
public void removeUser(...) {
    someInstance.departmentService.removeUserFromDepartments(user, depsids);
}

@Transactional
public List<?> getUsers(...) {
    return someInstance.departmentService.getDepartmentUsers(user.id);
}

然后最高级别是onEmailMessage()方法,它必须是非事务性的,并且在单独的类中,然后是上面的这两种方法。在这个级别中调用它们,它将起作用。

答案 1 :(得分:0)

您已将其标记为Transactional。执行所有查询后,DB中的更改将生效。所有操作都将被提交或不提交。

答案 2 :(得分:0)

事务尚未提交,因此不一定已将更改写入数据库。

您可以尝试拨打

entityManager.flush();

removeUserFromDepartments()之后但在getDepartmentUsers()之前强制在提交之前写入数据库更改。