【问题标题】:Best practices to follow for non transactional DB calls with Spring MVC and Hibernate使用 Spring MVC 和 Hibernate 进行非事务性 DB 调用的最佳实践
【发布时间】:2016-11-07 16:11:42
【问题描述】:

我正在开发一个在 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();
}

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

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 用户请求,那么它将打开 300 个对 DB 的 JDBC 调用(因为 sessionFactory.openSession() 创建一个新的 JDBC 调用)。

【问题讨论】:

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


【解决方案1】:

创建事务并不是一项昂贵的操作,因此在大多数典型应用程序使用情况下,包装执行只读操作的方法调用不会为您带来太多的性能。

但任何时候应用程序出于任何特定原因计划更改数据时,都应将其包装在事务中,尤其是在更改多个表时,例如更改实体关系等。这样可以确保多个 SQL 语句批处理在一起,并且仅在所有更改的提交时而不是之前对其他会话可见。这对于维护数据库完整性至关重要。

插入性能通常更依赖于其他因素,而不是您是否正在创建事务,例如您是否选择使用 IDENTITYAUTO_INCREMENTSEQUENCE 主键而不是自然键和/或是否您设置了正确的 JDBC 批处理大小。

此外,基于 Web 的应用程序在处理 Web 框架代码时可能会遭受比您担心是否使用事务更令人头疼的性能问题:)。

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-10-20
    • 2012-05-31
    • 1970-01-01
    • 1970-01-01
    • 2018-09-25
    • 2015-09-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多