在spring中使用声明型事务
spring使用aop机制管理jdbc的连接和事务。它使用TransactionInterceptor类,Spring事务支持中的核心接口是
org.springframework.transaction.PlatformTransactionManager。 为了实际执行事务,Spring所有的事务划分功能都通过传递适当的TransactionDefinition实例,委托给 PlatformTransactionManager。
尽管PlatformTransactionManager接口可以直接使用,应用程序通常配置具体的事务管理器并使用声明性事务来划分事务。
Spring具有多种PlatformTransactionManager实现,它们分为两类:
局 部事务策略即针对单个资源执行事务(主要是针对单个的数据库)。实现有 org.springframework.jdbc.datasource.DataSourceTransactionManager。它用于jdbc 数据源的配置,调用TransactionInterceptor开是一个事务,
从DataSource得到一个connection并确保auto-commit设为disabled。他用JdbcTemplate在一个线程内绑定一个JDBC connection,TransactionInterceptor负责提交事务,
DataSourceTransactionManager 调用Connection.commit()关闭connection,并解除绑定(potentially allowing for one thread connection per data source)。
例如
<bean id="DataSource" <br="">class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName">
<value>oracle.jdbc.driver.OracleDriver</value>
</property>
<property name="url">
<value>jdbc:oracle:thin:@localhost:1521:hua2</value>
</property>
<property name="username">
<value>user</value></property>
<property name="password">
<value>gotpassword</value>
</property>
</bean>
</beans>
<bean id="DataSourceTransactionManager" <br="">class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="DataSource">
</bean>
<bean id="tatanTransactionScriptsProxyCreator" <br="">class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
<property name="beanNames">
<list>
<idref bean="tatanTransactionScripts">
</list>
</property>
<property name="interceptorNames">
<list>
<idref bean="DataSourceTransactionInterceptor">
</list>
</property>
</bean>
<bean id="DataSourceTransactionInterceptor" <br="">class="org.springframework.transaction.interceptor.TransactionInterceptor">
<property name="transactionManager" <br="">ref="DataSourceTransactionManager" />
<property name="transactionAttributeSource">
<value>
com.tatan.tatanTransactionScriptsImpl.*=PROPAGATION_REQUIRED
</value>
</property>
</bean>
transactionAttributesSource 属性指定每个方法的transaction attribute,PROPAGATION_REQUIRED说明在一个事务内这个方法被执行。
和EJB一样,默认的情况下,spring只有当unchecked exception被抛出时,才rollback事务,也可以自己加入checked exception。
tatanTransactionScripts被TransactionInterceptor封装,在一个事物内执行类的每一个方法。
更为简单的配置
??? <bean id="UserManagerTran" <br="">??????????? class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
??????????? <property name="transactionManager">
??????????????? <ref bean="transactionManager"></property>
??????????? <property name="target"><ref bean="UserManager"></property>
??????????? <property name="transactionAttributes">
??????????????? <props>
??????????????????? <prop key="insert*">
??????????????????????? PROPAGATION_REQUIRED, ISOLATION_READ_COMMITTED</prop>
??????????????????? <prop key="tran*">
??????????????????????? PROPAGATION_REQUIRED, ISOLATION_SERIALIZABLE</prop>
??????????????????? <prop key="deposit*">
??????????????????????? PROPAGATION_REQUIRED, ISOLATION_READ_COMMITTED</prop>
??????????????? </props>
??????????? </property>
??????? </bean>
???????? <bean id="transactionManager" <br="">?????????? class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
?????????? <property name="dataSource"><ref bean="dataSource"></property>
?????? </bean>
(The TransactionProxyFactoryBean is a ProxyFactoryBean where every bean is adviced with a TransactionInterceptor. And the TransactionInterceptor is a piece of advice.
So you can use a seperate TransactionInterceptor and ProxyFactoryBean. But if you are lazy/smart, you can use the TransactionProxyFactoryBean that does the same thing (only less configuration needed))
对于特定的方法或方法命名模式,代理的具体事务行为由事务属性驱动,如下面的例子所示:
<prop key="insert*">
ROPAGATION_REQUIRED, ISOLATION_READ_COMMITTED
</prop>
key属性确定代理应该给哪个方法增加事务行为。这样的属性最重要的部份是传播行为。有以下选项可供使用:
PROPAGATION_REQUIRED--支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。
PROPAGATION_SUPPORTS--支持当前事务,如果当前没有事务,就以非事务方式执行。
PROPAGATION_MANDATORY--支持当前事务,如果当前没有事务,就抛出异常。
PROPAGATION_REQUIRES_NEW--新建事务,如果当前存在事务,把当前事务挂起。
PROPAGATION_NOT_SUPPORTED--以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
PROPAGATION_NEVER--以非事务方式执行,如果当前存在事务,则抛出异常。
PROPAGATION_NESTED--如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则进行与PROPAGATION_REQUIRED类似的操作。
前六个策略类似于EJB CMT,第七个(PROPAGATION_NESTED)是Spring所提供的一个特殊变量。
它要求事务管理器或者使用JDBC 3.0 Savepoint API提供嵌套事务行为(如Spring的DataSourceTransactionManager)。
事 务属性中的readOnly标志表示对应的事务应该被最优化为只读事务。这是一个最优化提示。在一些情况下,一些事务策略能够起到显著的最优化效果,例如 在使用Object/Relational映射工具(如:Hibernate或TopLink)时避免dirty checking(试图“刷新”)。
在事务属性中还有定义“timeout”值的选项,指定事务超时为几秒。在JTA中,这将被简单地传递到J2EE服务器的事务协调程序,并据此得到相应的解释。
spring使用aop机制管理jdbc的连接和事务。它使用TransactionInterceptor类,Spring事务支持中的核心接口是
org.springframework.transaction.PlatformTransactionManager。 为了实际执行事务,Spring所有的事务划分功能都通过传递适当的TransactionDefinition实例,委托给 PlatformTransactionManager。
尽管PlatformTransactionManager接口可以直接使用,应用程序通常配置具体的事务管理器并使用声明性事务来划分事务。
Spring具有多种PlatformTransactionManager实现,它们分为两类:
局 部事务策略即针对单个资源执行事务(主要是针对单个的数据库)。实现有 org.springframework.jdbc.datasource.DataSourceTransactionManager。它用于jdbc 数据源的配置,调用TransactionInterceptor开是一个事务,
从DataSource得到一个connection并确保auto-commit设为disabled。他用JdbcTemplate在一个线程内绑定一个JDBC connection,TransactionInterceptor负责提交事务,
DataSourceTransactionManager 调用Connection.commit()关闭connection,并解除绑定(potentially allowing for one thread connection per data source)。
例如
<bean id="DataSource" <br="">class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName">
<value>oracle.jdbc.driver.OracleDriver</value>
</property>
<property name="url">
<value>jdbc:oracle:thin:@localhost:1521:hua2</value>
</property>
<property name="username">
<value>user</value></property>
<property name="password">
<value>gotpassword</value>
</property>
</bean>
</beans>
<bean id="DataSourceTransactionManager" <br="">class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="DataSource">
</bean>
<bean id="tatanTransactionScriptsProxyCreator" <br="">class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
<property name="beanNames">
<list>
<idref bean="tatanTransactionScripts">
</list>
</property>
<property name="interceptorNames">
<list>
<idref bean="DataSourceTransactionInterceptor">
</list>
</property>
</bean>
<bean id="DataSourceTransactionInterceptor" <br="">class="org.springframework.transaction.interceptor.TransactionInterceptor">
<property name="transactionManager" <br="">ref="DataSourceTransactionManager" />
<property name="transactionAttributeSource">
<value>
com.tatan.tatanTransactionScriptsImpl.*=PROPAGATION_REQUIRED
</value>
</property>
</bean>
transactionAttributesSource 属性指定每个方法的transaction attribute,PROPAGATION_REQUIRED说明在一个事务内这个方法被执行。
和EJB一样,默认的情况下,spring只有当unchecked exception被抛出时,才rollback事务,也可以自己加入checked exception。
tatanTransactionScripts被TransactionInterceptor封装,在一个事物内执行类的每一个方法。
更为简单的配置
??? <bean id="UserManagerTran" <br="">??????????? class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
??????????? <property name="transactionManager">
??????????????? <ref bean="transactionManager"></property>
??????????? <property name="target"><ref bean="UserManager"></property>
??????????? <property name="transactionAttributes">
??????????????? <props>
??????????????????? <prop key="insert*">
??????????????????????? PROPAGATION_REQUIRED, ISOLATION_READ_COMMITTED</prop>
??????????????????? <prop key="tran*">
??????????????????????? PROPAGATION_REQUIRED, ISOLATION_SERIALIZABLE</prop>
??????????????????? <prop key="deposit*">
??????????????????????? PROPAGATION_REQUIRED, ISOLATION_READ_COMMITTED</prop>
??????????????? </props>
??????????? </property>
??????? </bean>
???????? <bean id="transactionManager" <br="">?????????? class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
?????????? <property name="dataSource"><ref bean="dataSource"></property>
?????? </bean>
(The TransactionProxyFactoryBean is a ProxyFactoryBean where every bean is adviced with a TransactionInterceptor. And the TransactionInterceptor is a piece of advice.
So you can use a seperate TransactionInterceptor and ProxyFactoryBean. But if you are lazy/smart, you can use the TransactionProxyFactoryBean that does the same thing (only less configuration needed))
对于特定的方法或方法命名模式,代理的具体事务行为由事务属性驱动,如下面的例子所示:
<prop key="insert*">
ROPAGATION_REQUIRED, ISOLATION_READ_COMMITTED
</prop>
key属性确定代理应该给哪个方法增加事务行为。这样的属性最重要的部份是传播行为。有以下选项可供使用:
PROPAGATION_REQUIRED--支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。
PROPAGATION_SUPPORTS--支持当前事务,如果当前没有事务,就以非事务方式执行。
PROPAGATION_MANDATORY--支持当前事务,如果当前没有事务,就抛出异常。
PROPAGATION_REQUIRES_NEW--新建事务,如果当前存在事务,把当前事务挂起。
PROPAGATION_NOT_SUPPORTED--以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
PROPAGATION_NEVER--以非事务方式执行,如果当前存在事务,则抛出异常。
PROPAGATION_NESTED--如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则进行与PROPAGATION_REQUIRED类似的操作。
前六个策略类似于EJB CMT,第七个(PROPAGATION_NESTED)是Spring所提供的一个特殊变量。
它要求事务管理器或者使用JDBC 3.0 Savepoint API提供嵌套事务行为(如Spring的DataSourceTransactionManager)。
事 务属性中的readOnly标志表示对应的事务应该被最优化为只读事务。这是一个最优化提示。在一些情况下,一些事务策略能够起到显著的最优化效果,例如 在使用Object/Relational映射工具(如:Hibernate或TopLink)时避免dirty checking(试图“刷新”)。
在事务属性中还有定义“timeout”值的选项,指定事务超时为几秒。在JTA中,这将被简单地传递到J2EE服务器的事务协调程序,并据此得到相应的解释。