且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

Spring 管理的事务没有@Transactional 注释

更新时间:2023-10-06 10:43:46

根据文档(Spring 文档)它只是元数据,表明方法或接口可以通过事务感知"的东西进行配置(即 <tx:annotation-driven/>).

According to the documentation (Spring docs) it's just metadata to give an indication that the method or interface can be configured by something that is 'transactionally aware' (i.e. <tx:annotation-driven/>).

仅使用 tx:annotation-driven 而没有 @Transactional 属性,我相信您会应用默认"事务性:

With just tx:annotation-driven and no @Transactional attribute I believe you get the "default" transactionality applied:

  • 传播设置必需.
  • 隔离级别为默认.
  • 事务是读/写的.
  • 事务超时默认为底层事务系统的默认超时,如果不支持超时,则无.
  • 任何 RuntimeException 都会触发回滚,而任何检查的 Exception 都不会.
  • Propagation setting is REQUIRED.
  • Isolation level is DEFAULT.
  • Transaction is read/write.
  • Transaction timeout defaults to the default timeout of the underlying transaction system, or none if timeouts are not supported.
  • any RuntimeException triggers rollback, and any checked Exception does not.

假设您使用 <tx:annotation-driven/> 通过事务管理器驱动它,然后错过 @Transactional 属性意味着您可以不应用诸如 readOnlyisolationpropagationrollbackFornoRollbackFor 之类的属性等

Assuming you're using the <tx:annotation-driven /> to drive it via a transaction manager then missing out the @Transactional attribute means you can't apply such properties as readOnly, isolation, propagation, rollbackFor, noRollbackFor etc.

我相信 MVC 略有不同 - Hibernate 会话直接绑定到 MVC 请求 - 即当收到请求时,事务开始.

I believe that MVC is slightly different - the Hibernate session is tied directly to the MVC request - i.e. when the request is received the transaction starts.

回到你的例子,HibernateDAOSupport中getSession()的代码如下:

Back to your example, the code for getSession() in HibernateDAOSupport is as follows:

protected final Session getSession()
    throws DataAccessResourceFailureException, IllegalStateException 
{
    return getSession(this.hibernateTemplate.isAllowCreate());
}

依次调用:

/**
 * Obtain a Hibernate Session, either from the current transaction or
 * a new one. The latter is only allowed if "allowCreate" is true.
 *.......
 */
protected final Session getSession()
    throws DataAccessResourceFailureException, IllegalStateException {
    return getSession(this.hibernateTemplate.isAllowCreate());
}

最终调用:

/** 
 * ....
 * @param allowCreate whether a non-transactional Session should be created
 * when no transactional Session can be found for the current thread
 * ....
 */
private static Session doGetSession(
    SessionFactory sessionFactory, Interceptor entityInterceptor,
SQLExceptionTranslator jdbcExceptionTranslator, boolean allowCreate)

从根本上说,一个事务:会话是 1:1 AFAIK 绑定的,没有事务运行的唯一方法是使用 JBoss,它有一个烘焙"持久层,为您提供事务性(在幕后).即使你在 getSession() 之后调用 getQuery() 你仍然有效地有一个事务发生,因为它是一个 JDBC/Hibernate 连接.

Fundamentally, a Transaction:Session is tied 1:1 AFAIK, and the only way to run without a transaction is by using say JBoss which has a 'baked in' persistence layer which provides the transactionality for you (under the covers). Even if you call getQuery() after getSession() you still effectively have a transaction occurring as it's a JDBC/Hibernate connection.