1

请考虑 Spring 中的以下情况(我正在使用 Spring 4.0.0 GA 和 Hibernate 4.3.5 final)。

@Service
@Transactional(readOnly = true, propagation=Propagation.REQUIRED)
public final class ChangePasswordDAO implements ChangePasswordService
{
    @PersistenceContext
    private EntityManager entityManager;

    public void setEntityManager(EntityManager entityManager)
    {
        this.entityManager = entityManager;
    }

    @Override
    @SuppressWarnings("unchecked")
    public String getOldPassword(UserTable userTable)
    {
        CriteriaBuilder criteriaBuilder=entityManager.getCriteriaBuilder();
        CriteriaQuery<String>criteriaQuery=criteriaBuilder.createQuery(String.class);
        Root<UserTable> root = criteriaQuery.from(entityManager.getMetamodel().entity(UserTable.class));
        criteriaQuery.multiselect(root.get(UserTable_.password));
        criteriaQuery.where(criteriaBuilder.equal(root, userTable));
        List<String> list = entityManager.createQuery(criteriaQuery).getResultList();
        return list!=null&&!list.isEmpty()?list.get(0):null;
    }

    @Override
    @SuppressWarnings("unchecked")        
    public boolean changePassword(String password, UserTable userTable)
    {
        CriteriaBuilder criteriaBuilder=entityManager.getCriteriaBuilder();
        CriteriaUpdate<UserTable> criteriaUpdate=criteriaBuilder.createCriteriaUpdate(UserTable.class);
        Root<UserTable> root = criteriaUpdate.from(entityManager.getMetamodel().entity(UserTable.class));
        criteriaUpdate.set(root.get(UserTable_.password), password);
        criteriaUpdate.set(root.get(UserTable_.lastModified), DateTime.now(DateTimeZone.UTC));
        criteriaUpdate.where(criteriaBuilder.equal(root, userTable));
        return entityManager.createQuery(criteriaUpdate).executeUpdate()>0;
    }
}

在这种情况下,我期望以下行

@Transactional(readOnly = false, propagation=Propagation.REQUIRED)

changePassword()方法之前,以便@Transactional可以覆盖类级别的注释。否则,类级别注释使用readOnly = true也适用于此方法。因此,更新操作不应该发生,因为事务是只读的。

那么在这种情况下 Spring 是如何进行更新操作的呢?

4

1 回答 1

0

事务注释必须在服务层,而不是在 DAO 层。

每个 DAO 方法都应该执行一个操作,因此在这一层中使用它是没有意义的。

如果需要多个操作,则将从服务层方法调用各种 DAO 方法。

于 2019-07-04T07:54:04.440 回答