简体   繁体   中英

Rollback Spring JDBC operation when not in transaction

I am using annotation driven transaction management with Spring JDBC.

I would like to have Spring throw an exception when by mistake I forgot to annotate with @Transactional a service method that inserts/updates/deletes.

By default data can be inserted/updated/deleted even not within a transaction.

You can use Propagation.MANDATORY in your DAO layer.

Propagation.MANDATORY will not start a transaction. It will check whether perticular method is attached to a transaction or not, if not container will throw an exception.

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' (ie

With just tx:annotation-driven and no @Transactional attributes 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. ny RuntimeException triggers rollback, and any checked Exception does not. Assuming you're using the tx:annotation 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 - ie 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 occuring as it's a JDBC/Hibernate connection.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM