Spring中JdbcTemplate执行SQL出错不回滚?

在Spring中为了方便用户对数据库的操作,Spring提供了JdbcTemplate以及HibernateTemplate。今天,查看这两个类源码,发现一问题,令我费解,请知道的朋友指点一下。
大致问题就是,在JdbcTemplate的execute(..)方法中,执行SQL抛出异常时,居然没出现回滚代码,具体代码我贴出来,方便大家参考,至于疑问,我也在代码中以注释的形式标出来了,请大家帮忙解释一下,谢谢!

[code="java"]public Object execute(StatementCallback action) throws DataAccessException {
Assert.notNull(action, "Callback object must not be null");

    Connection con = DataSourceUtils.getConnection(getDataSource());
    Statement stmt = null;
    try {
        Connection conToUse = con;
        if (this.nativeJdbcExtractor != null &&
                this.nativeJdbcExtractor.isNativeConnectionNecessaryForNativeStatements()) {
            conToUse = this.nativeJdbcExtractor.getNativeConnection(con);
        }
        stmt = conToUse.createStatement();
        applyStatementSettings(stmt);
        Statement stmtToUse = stmt;
        if (this.nativeJdbcExtractor != null) {
            stmtToUse = this.nativeJdbcExtractor.getNativeStatement(stmt);
        }
        Object result = action.doInStatement(stmtToUse);  //执行SQL语句
        SQLWarning warning = stmt.getWarnings();
        throwExceptionOnWarningIfNotIgnoringWarnings(warning);
        return result;
    }
    catch (SQLException ex) { 
        /*
         * 加入执行SQL时抛出异常,一般来说应该回滚的,但是现在没有出现con.rollback()
         */
        // Release Connection early, to avoid potential connection pool deadlock
        // in the case when the exception translator hasn't been initialized yet.
        JdbcUtils.closeStatement(stmt);
        stmt = null;
        DataSourceUtils.releaseConnection(con, getDataSource());
        con = null;
        throw getExceptionTranslator().translate("StatementCallback", getSql(action), ex);
    }
    finally {
        JdbcUtils.closeStatement(stmt);
        DataSourceUtils.releaseConnection(con, getDataSource());
    }
}[/code]

谢谢大家耐心观看以及分析!

具体代码我还没看过,不过我觉得应该注意
Connection con = DataSourceUtils.getConnection(getDataSource());

con应该是在一个线程中保存的。注意到了吗,con也没有commit。
在一个事务开始的时候,con打开,并在操作后保存到线程中。当整个事务完成或失败时,才进行commit或callback。

是否执行了一些DDL语句,一般这些操作是没有事务的。

sorry,没有仔细看。
Spring是可以使用声明事务的。 [url]http://doc.javanb.com/spring-framework-reference-zh-2-0-5/ch09s05.html[/url]

这样更灵活。

回滚事务又不是在JdbcTemplate以及HibernateTemplate里进行编程处理的,
你没看到它又抛出异常了吗
throw getExceptionTranslator().translate("StatementCallback", getSql(action), ex);

这是和spring的声明式事务管理是相关联的,

通 常通过TransactionProxyFactoryBean设置Spring事务代理。我们需 要一个目标对象包装在事务代理中。这个目标对象一般是一个普通Java对象的bean。当我 们定义TransactionProxyFactoryBean时,必须提供一个相关的 PlatformTransactionManager的引用和事务属性。 事务属性含有上面描述的事务定义。

class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">




PROPAGATION_REQUIRED,-MyCheckedException
PROPAGATION_REQUIRED
PROPAGATION_REQUIRED,readOnly



事 务代理会实现目标对象的接口:这里是id为petStoreTarget的bean。(使用 CGLIB也可以实现具体类的代理。只要设置proxyTargetClass属性为true就可以。 如果目标对象没有实现任何接口,这将自动设置该属性为true。通常,我们希望面向接口而不是 类编程。)使用proxyInterfaces属性来限定事务代理来代 理指定接口也是可以的(一般来说是个好想法)。也可以通过从 org.springframework.aop.framework.ProxyConfig继承或所有AOP代理工厂共享 的属性来定制TransactionProxyFactoryBean的行为。

这里的transactionAttributes属性定义在 org.springframework.transaction.interceptor.NameMatchTransactionAttributeSource 中的属性格式来设置。这个包括通配符的方法名称映射是很直观的。注意 insert*的映射的值包括回滚规则。添加的-MyCheckedException 指定如果方法抛出MyCheckedException或它的子类,事务将 会自动回滚。可以用逗号分隔定义多个回滚规则。-前缀强制回滚,+前缀指定提交(这允许即使抛出unchecked异常时也可以提交事务,当然你自己要明白自己 在做什么)。

TransactionProxyFactoryBean允许你通过 “preInterceptors”和“postInterceptors”属性设置“前”或“后”通知来提供额外的 拦截行为。可以设置任意数量的“前”和“后”通知,它们的类型可以是 Advisor(可以包含一个切入点), MethodInterceptor或被当前Spring配置支持的通知类型 (例如ThrowAdvice, AfterReturningtAdvice或BeforeAdvice, 这些都是默认支持的)。这些通知必须支持实例共享模式。如果你需要高级AOP特 性来使用事务,如有状态的maxin,那最好使用通用的 org.springframework.aop.framework.ProxyFactoryBean, 而不是TransactionProxyFactoryBean实用代理创建者。

也可以设置自动代理:配置AOP框架,不需要单独的代理定义类就可以生成类的 代理。

附两个spring的事务配置例子:

PROPAGATION_REQUIRES_NEW, -MyException

[color=red]注:上面的意思是add方法将独占一个事务,当事务处理过程中产生MyException异常或者该异常的子类将回滚该事务。[/color]


PROPAGATION_SUPPORTS, ISOLATION_READ_COMMITED, Readonly

注:表示loadAll方法支持事务,而且不会读取没有提交事务的数据。它的数据为只读(这样有助于提高读取的性能)

附A Spring中的所有事务策略

PROPAGATION_MANDATORY
PROPAGATION_NESTED
PROPAGATION_NEVER
PROPAGATION_NOT_SUPPORTED
PROPAGATION_REQUIRED
PROPAGATION_REQUIRED_NEW
PROPAGATION_SUPPORTS

附B Spring中所有的隔离策略:

ISOLATION_DEFAULT
ISOLATION_READ_UNCOMMITED
ISOLATION_COMMITED
ISOLATION_REPEATABLE_READ
ISOLATION_SERIALIZABLE