本站首页    管理页面    写新日志    退出


«September 2025»
123456
78910111213
14151617181920
21222324252627
282930


公告

戒除浮躁,读好书,交益友


我的分类(专题)

日志更新

最新评论

留言板

链接

Blog信息
blog名称:邢红瑞的blog
日志总数:523
评论数量:1142
留言数量:0
访问次数:9712064
建立时间:2004年12月20日




[java语言]在spring中使用声明型事务
原创空间,  网上资源,  软件技术

邢红瑞 发表于 2006/1/8 18:34:39

在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"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"class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="DataSource" /></bean><bean id="tatanTransactionScriptsProxyCreator"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"class="org.springframework.transaction.interceptor.TransactionInterceptor"><property name="transactionManager"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"            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"           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类是org.springframework.transaction.jta.JtaTransactionManager,它委托给遵循JTA规范的J2EE服务器,也有例外。 spring支持JTA,只需要一个标准的JtaTransactionManager定义,数据库必须支持XA protocol,或者J2EE服务器提供支持XA规范的DataSource。默认的Spring JtaTransactionManager设置将从标准的JNDI位置获取JTA的javax.transaction.UserTransaction对象,该JNDI位置由J2EE指定:java:comp/UserTransaction。对于大多数标准J2EE环境下的用例来说,它工作良好。但是,默认的JtaTransactionManager不能执行事务挂起操作(即它不支持PROPAGATION_REQUIRES_NEW和PROPAGATION_NOT_SUPPORTED)。原因是标准的JTA UserTransaction接口不支持挂起或恢复事务的操作;它只支持开始和完成新事务的操作。为执行事务挂起操作,还需要提供javax.transaction.TransactionManager实例,按照JTA的规定,它提供标准的挂起和恢复方法。遗憾的是,J2EE没有为JTA TransactionManager定义标准的JNDI位置!因此,必须使用特定于供应商的(vendor-specific)查寻机制。J2EE没有考虑把JTA TransactionManager接口作为它的公开API的一部分。JTA规范规定的TransactionManager接口原本是打算用于容器集成的。但是为JTA TransactionManager定义标准的JNDI位置还是有重大意义的,尤其是对于轻量级容器(如Spring);然后,便可以以同样的方式来定位任意的J2EE服务器的JTA TransactionManager。结合jboss JTA的Spring事务划分oracle-ds.xml<?xml version="1.0" encoding="UTF-8"?> <datasources> <xa-datasource>  <jndi-name>XASpringDS</jndi-name>  <track-connection-by-tx/>  <isSameRM-override-value>false</isSameRM-override-value>  <xa-datasource-class>oracle.jdbc.xa.client.OracleXADataSource</xa-datasource-class>  <xa-datasource-property name="URL">jdbc:oracle:oci8:@orcl</xa-datasource-property>  <xa-datasource-property name="User">SCOTT</xa-datasource-property>  <xa-datasource-property name="Password">tiger</xa-datasource-property>  <exception-sorter-class-name>org.jboss.resource.adapter.jdbc.vendor.OracleExceptionSorter</exception-sorter-class-name>  <no-tx-separate-pools/> </xa-datasource> <mbean   code="org.jboss.resource.adapter.jdbc.xa.oracle.OracleXAExceptionFormatter"   name="jboss.jca:service=OracleXAExceptionFormatter">  <depends optional-attribute-name="TransactionManagerService">   jboss:service=TransactionManager</depends> </mbean></datasources>spring配置<!-- Data source bean -->  <bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">  <property name="jndiName"><value>java:/XASpringDS</value></property> </bean>  <bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager"/> Spring有效地将DAO实现从实际的运行时环境中分离出来,允许在J2EE容器之外轻松地测试或重用用。Spring提供了多种事务策略,比如JtaTransactionManager和JDBC DataSourceTransactionManager,前者委托给J2EE服务器的事务协调程序,后者则针对单个JDBC DataSource(即单个的目标数据库)执行事务。通过对后端配置进行简单的更改,就能够轻松地调整事务策略适应另一个环境。  


阅读全文(10245) | 回复(1) | 编辑 | 精华
 


回复:在spring中使用声明型事务
原创空间,  网上资源,  软件技术

ggg(游客)发表评论于2006/11/28 9:20:22

bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb


个人主页 | 引用回复 | 主人回复 | 返回 | 编辑 | 删除
 


» 1 »

发表评论:
昵称:
密码:
主页:
标题:
验证码:  (不区分大小写,请仔细填写,输错需重写评论内容!)



站点首页 | 联系我们 | 博客注册 | 博客登陆

Sponsored By W3CHINA
W3CHINA Blog 0.8 Processed in 0.047 second(s), page refreshed 144783605 times.
《全国人大常委会关于维护互联网安全的决定》  《计算机信息网络国际联网安全保护管理办法》
苏ICP备05006046号