解惑 spring 嵌套事务
/**
* @author 王政
* @date 2006-11-24
* @note 转载请注明出处
*/
在所有使用 spring 的应用中, 声明式事务管理可能是使用率最高的功能了, 但是, 从我观察到的情况看,
绝大多数人并不能深刻理解事务声明中不同事务传播属性配置的的含义, 让我们来看一下 TransactionDefinition 接口中的定义
- /**
- * Support a current transaction, create a new one if none exists.
- * Analogous to EJB transaction attribute of the same name.
- * <p>This is typically the default setting of a transaction definition.
- */
- int PROPAGATION_REQUIRED = 0;
- /**
- * Support a current transaction, execute non-transactionally if none exists.
- * Analogous to EJB transaction attribute of the same name.
- * <p>Note: For transaction managers with transaction synchronization,
- * PROPAGATION_SUPPORTS is slightly different from no transaction at all,
- * as it defines a transaction scopp that synchronization will apply for.
- * As a consequence, the same resources (JDBC Connection, Hibernate Session, etc)
- * will be shared for the entire specified scope. Note that this depends on
- * the actual synchronization configuration of the transaction manager.
- * @see org.springframework.transaction.support.AbstractPlatformTransactionManager#setTransactionSynchronization
- */
- int PROPAGATION_SUPPORTS = 1;
- /**
- * Support a current transaction, throw an exception if none exists.
- * Analogous to EJB transaction attribute of the same name.
- */
- int PROPAGATION_MANDATORY = 2;
- /**
- * Create a new transaction, suspend the current transaction if one exists.
- * Analogous to EJB transaction attribute of the same name.
- * <p>Note: Actual transaction suspension will not work on out-of-the-box
- * on all transaction managers. This in particular applies to JtaTransactionManager,
- * which requires the <code>javax.transaction.TransactionManager</code> to be
- * made available it to it (which is server-specific in standard J2EE).
- * @see org.springframework.transaction.jta.JtaTransactionManager#setTransactionManager
- */
- int PROPAGATION_REQUIRES_NEW = 3;
- /**
- * Execute non-transactionally, suspend the current transaction if one exists.
- * Analogous to EJB transaction attribute of the same name.
- * <p>Note: Actual transaction suspension will not work on out-of-the-box
- * on all transaction managers. This in particular applies to JtaTransactionManager,
- * which requires the <code>javax.transaction.TransactionManager</code> to be
- * made available it to it (which is server-specific in standard J2EE).
- * @see org.springframework.transaction.jta.JtaTransactionManager#setTransactionManager
- */
- int PROPAGATION_NOT_SUPPORTED = 4;
- /**
- * Execute non-transactionally, throw an exception if a transaction exists.
- * Analogous to EJB transaction attribute of the same name.
- */
- int PROPAGATION_NEVER = 5;
- /**
- * Execute within a nested transaction if a current transaction exists,
- * behave like PROPAGATION_REQUIRED else. There is no analogous feature in EJB.
- * <p>Note: Actual creation of a nested transaction will only work on specific
- * transaction managers. Out of the box, this only applies to the JDBC
- * DataSourceTransactionManager when working on a JDBC 3.0 driver.
- * Some JTA providers might support nested transactions as well.
- * @see org.springframework.jdbc.datasource.DataSourceTransactionManager
- */
- int PROPAGATION_NESTED = 6;
可以看到 Savepoint 是 SavepointManager.createSavepoint 实现的, 再看 SavepointManager 的层次结构, 发现
其 Template 实现是 JdbcTransactionObjectSupport, 常用的 DatasourceTransactionManager, HibernateTransactionManager
中的 TransactonObject 都是它的子类 :
JdbcTransactionObjectSupport 告诉我们必须要满足两个条件才能 createSavepoint :
2. java.sql.Savepoint 必须存在, 即 jdk 版本要 1.4+
3. Connection.getMetaData().supportsSavepoints() 必须为 true, 即 jdbc drive 必须支持 JDBC 3.0
确保以上条件都满足后, 你就可以尝试使用 PROPAGATION_NESTED 了. (全文完)