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/>
).
With just tx:annotation-driven and no @Transactional
attribute I believe you get the "default" transactionality applied:
- 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.
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.
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.
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());
}
Which in turn calls to:
/**
* 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());
}
which ultimately calls to :
/**
* ....
* @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)
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.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…