使用Spring MVC和Hibernate进行非事务性DB调用的最佳实践

时间:2016-07-05 18:10:41

标签: spring hibernate spring-mvc jdbc spring-transactions

我正在使用Spring服务类上的@Transactional注释开发一个应用程序。要访问db层,我有AbstractDao类,它在需要时返回当前会话。即

@Autowired
@Qualifier("sessionFactory")
private SessionFactory sessionFactory;

protected Session getSession() {
    session = sessionFactory.getCurrentSession();
}

protected Criteria createEntityCriteria() {
    return getSession().createCriteria(persistentClass);
}

public List<T> findByCriteria(Criterion criterion) {
    Criteria criteria = createEntityCriteria();
    criteria.add(criterion);
    return criteria.list();
}

我正在考虑删除跨国支持,因为我真的不需要它,我想提高db调用的性能,因为我必须每秒支持许多db插入。

1)在Hibernate和Spring中使用非跨国数据库操作是否可以?

2)那么如何更改上面的代码以支持非事务?  我可以创建如下代码吗?

private Session session;
protected Session getSession() {
    if (session == null) {
        session = sessionFactory.openSession();
    }
    return session;
}

因此createEntityCriteria()可以调用getSession()获取会话。因此,我们可以使用上面的代码管理每个用户请求(HTTP spring MVC请求)的一个会话。

如果可以,那么我应该在用户请求结束时关闭会话吗?因此,如果每秒有300个MVC用户请求,那么它将向DB打开300个JDBC调用(因为sessionFactory.openSession()创建一个新的JDBC调用)。

1 个答案:

答案 0 :(得分:0)

创建事务并不是一项昂贵的操作,因此在最典型的应用程序使用情况下,包装执行只读操作的方法调用不会对性能产生很大影响。

但是,只要应用程序计划因任何特定原因更改数据,它就应该包含在事务中,特别是如果您要更改多个表,例如更改实体关系等。这样可以确保多个表SQL语句一起批处理,只有在所有更改的提交时才可见,而不是之前。这对于维护数据库完整性至关重要。

除了您是否创建了一项交易,例如您是否选择使用IDENTITYAUTO_INCREMENTSEQUENCE主键,插入效果通常更依赖于其他因素与自然键和/或是否设置正确的JDBC批处理大小。

此外,基于网络的应用程序在Web框架处理代码中可能会遇到比在关注您是否正在使用事务时更多的性能问题:)。

关于JDBC调用,这又是连接池有用的地方。

它只向应用程序发出指定的最大连接数,一旦达到该上限,可以告知进一步的连接请求等待几秒钟,希望连接可用或立即抛出异常,允许应用程序根据需要处理它。