- 浏览: 91770 次
- 性别:
- 来自: 上海
文章分类
最新评论
-
hvang1988:
...
Spring --- Transaction Management -
Branding:
谢谢,原来总是记不住,这下知道原理了
“Hello Java” -- Java安装
一)spring的事务管理
事务管理并非spring独有,用过JDBC hibernate的朋友都知道,这些api和框架都提供了自己的事务管理机制。那么spring的事务管理又有些什么与众不同支持呢?它的优点又有哪些呢?总结来说大概有以下这么几点:
1' 为不同的事务API提供一致的编程模型,如Java Transaction API (JTA)、JDBC、Hibernate、JavaPersistenceAPI(JPA)以及JavaDataObjects(JDO)
2' 支持declarative transaction management(声明式事务管理)
3' 为一些原本比较复杂的事务API提供简化的programmatic transaction management(编程式事务管理)API
4' 出色的整合Spring数据访问抽象
学习spring的事务管理的过程其实也就是通过例子理解以上4大优点的过程。所以下面,我们就结合实际的例子来慢慢分析这些优点吧 ^.^
二)整合Spring数据访问抽象
JDBC
它使用的是transaction manager类是:DataSourceTransactionManager。此外还定义了jdbc datasource。
JTA
如果你datasource使用的是JNDI技术,并且通过JTA的API来进行事务管理,那么你的配置将会是这样:
它对应的transaction mangager类是:JtaTransactionManager
Hibernate
如果你使用过hibernate,你就知道hibernate中的sessionFactory对象是其核心控制类。它掌管着orm转换、连接配置、日志格式等众多属性配置。spring则在此基础上再做了一层封装以用于事务管理。所以配置样式如下:
这里的datasource bean的配置和上面JDBC的例子中的一样,故这里就不再重复列出了。这里的transaction mangager类是HibernateTransactionManager
总结来说:当我们使用JDBC时,我们调用的是DataSourceTransactionManager;当我们使用JTA时,我们调用的是JtaTransactionManager;而当我们使用Hibernate时,我们调用的是HibernateTransactionManager...其实,spring的事务管理,不论你最终采用哪种技术,它都是接口PlatformTransactionManager的一种实现。如果你进一步研究一下PlatformTransactionManager接口,你就会明白spring是如何将众多数据访问方法抽象统一的了:
这里需要重点说明的是getTransaction(..)方法。它根据传入的TransactionDefinition类(它携带Isolation Propagation Timeout Read-only status等信息)来返回一个TransactionStatus类来代表新的一个事务或已存在的事务。有了这些接口,你完全可以自定义自己的transaction manager类。但还是那句话,绝大多数情况下,我们不需要这么做。spring已经为我们准备好了足够丰富的transaction manager类。
三)声明式事务管理
依赖于spring AOP。我们举例说明,假设我们需要对接口FooService下所有类进行事务管理:
那么我们可以配置如下:
对于回滚事务,我们可以指定:
上例显示的指出,对于NoProductInStockException,我们做回滚处理。此外<tx:method/>可以对propagation isolation做相应的设定。
四)编程式事务管理
如果你要使用编程式的事务管理(适合少量需要事务管理的情形)。那么两个类可供你选择使用:TransactionTemplate 和 PlatformTransactionManager
1' TransactionTemplate
先是有返回值的情况:
无返回值的情况:
还可以进行一些属性的设置:
2' PlatformTransactionManager
有之前声明式事务管理的介绍,相信将PlatformTransactionManager转换为编程式的事务管理就简单了:
五) propagation和isolation
1' propagation
1、PROPAGATION_REQUIRED:如果存在一个事务,则支持当前事务。如果没有事务则开启。
2、PROPAGATION_SUPPORTS:如果存在一个事务,支持当前事务。如果没有事务,则非事务的执行。
3、PROPAGATION_MANDATORY:如果已经存在一个事务,支持当前事务。如果没有一个活动的事务,则抛出异常。
4、PROPAGATION_REQUIRES_NEW:总是开启一个新的事务。如果一个事务存在,则将这个存在的事务挂起。
5、PROPAGATION_NOT_SUPPORTED:总是非事务地执行,并挂起任何存在的事务。
6、PROPAGATION_NEVER:总是非事务地执行,如果存在一个活动事务,则抛出异常。
7、PROPAGATION_NESTED:如果一个活动的事务存在,则运行在一个嵌套的事务中,如果没有活动事务,则按TransactionDefinition.PROPAGATION_REQUIRED属性执行
2' isolation
1、ISOLATION_DEFAULT: 这是一个PlatfromTransactionManager默认的隔离级别,使用数据库默认的事务隔离级别。
2、ISOLATION_READ_UNCOMMITTED:这是事务最低的隔离级别,它允许另外一个事务可以看到这个事务未提交的数据。
3、ISOLATION_READ_COMMITTED:保证一个事务修改的数据提交后才能被另外一个事务读取。另外一个事务不能读取该事务未提交的数据。
4、ISOLATION_REPEATALBE_READ: 这种事务隔离级别可以防止脏读,不可重复读。但是可能出现幻想读。它除了保证一个事务不能读取另外一个事务未提交的数据外,还保证了避免下面的情况产生(不可重复读)。
5、ISOLATION_SERIALIZABLE 这是花费最高代价但是最可靠的事务隔离级别。事务被处理为顺序执行。除了防止脏读,不课重复读外,还避免了幻想读。
事务管理并非spring独有,用过JDBC hibernate的朋友都知道,这些api和框架都提供了自己的事务管理机制。那么spring的事务管理又有些什么与众不同支持呢?它的优点又有哪些呢?总结来说大概有以下这么几点:
1' 为不同的事务API提供一致的编程模型,如Java Transaction API (JTA)、JDBC、Hibernate、JavaPersistenceAPI(JPA)以及JavaDataObjects(JDO)
2' 支持declarative transaction management(声明式事务管理)
3' 为一些原本比较复杂的事务API提供简化的programmatic transaction management(编程式事务管理)API
4' 出色的整合Spring数据访问抽象
学习spring的事务管理的过程其实也就是通过例子理解以上4大优点的过程。所以下面,我们就结合实际的例子来慢慢分析这些优点吧 ^.^
二)整合Spring数据访问抽象
JDBC
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> <property name="driverClassName" value="${jdbc.driverClassName}" /> <property name="url" value="${jdbc.url}" /> <property name="username" value="${jdbc.username}" /> <property name="password" value="${jdbc.password}" /> </bean> <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"/> </bean>
它使用的是transaction manager类是:DataSourceTransactionManager。此外还定义了jdbc datasource。
JTA
如果你datasource使用的是JNDI技术,并且通过JTA的API来进行事务管理,那么你的配置将会是这样:
<jee:jndi-lookup id="dataSource" jndi-name="jdbc/jpetstore"/> <bean id="txManager" class="org.springframework.transaction.jta.JtaTransactionManager" />
它对应的transaction mangager类是:JtaTransactionManager
Hibernate
如果你使用过hibernate,你就知道hibernate中的sessionFactory对象是其核心控制类。它掌管着orm转换、连接配置、日志格式等众多属性配置。spring则在此基础上再做了一层封装以用于事务管理。所以配置样式如下:
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"> <property name="dataSource" ref="dataSource" /> <property name="mappingResources"> <list> <value>org/springframework/samples/petclinic/hibernate/petclinic.hbm.xml</value> </list> </property> <property name="hibernateProperties"> <value>hibernate.dialect=${hibernate.dialect}</value> </property> </bean> <bean id="txManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> <property name="sessionFactory" ref="sessionFactory" /> </bean>
这里的datasource bean的配置和上面JDBC的例子中的一样,故这里就不再重复列出了。这里的transaction mangager类是HibernateTransactionManager
总结来说:当我们使用JDBC时,我们调用的是DataSourceTransactionManager;当我们使用JTA时,我们调用的是JtaTransactionManager;而当我们使用Hibernate时,我们调用的是HibernateTransactionManager...其实,spring的事务管理,不论你最终采用哪种技术,它都是接口PlatformTransactionManager的一种实现。如果你进一步研究一下PlatformTransactionManager接口,你就会明白spring是如何将众多数据访问方法抽象统一的了:
public interface PlatformTransactionManager { TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException; void commit(TransactionStatus status) throws TransactionException; void rollback(TransactionStatus status) throws TransactionException; }
这里需要重点说明的是getTransaction(..)方法。它根据传入的TransactionDefinition类(它携带Isolation Propagation Timeout Read-only status等信息)来返回一个TransactionStatus类来代表新的一个事务或已存在的事务。有了这些接口,你完全可以自定义自己的transaction manager类。但还是那句话,绝大多数情况下,我们不需要这么做。spring已经为我们准备好了足够丰富的transaction manager类。
三)声明式事务管理
依赖于spring AOP。我们举例说明,假设我们需要对接口FooService下所有类进行事务管理:
// the service interface that we want to make transactional package x.y.service; public interface FooService { Foo getFoo(String fooName); Foo getFoo(String fooName, String barName); void insertFoo(Foo foo); void updateFoo(Foo foo); } // an implementation of the above interface package x.y.service; public class DefaultFooService implements FooService { public Foo getFoo(String fooName) { throw new UnsupportedOperationException(); } public Foo getFoo(String fooName, String barName) { throw new UnsupportedOperationException(); } public void insertFoo(Foo foo) { throw new UnsupportedOperationException(); } public void updateFoo(Foo foo) { throw new UnsupportedOperationException(); } }
那么我们可以配置如下:
<!-- from the file 'context.xml' --> <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd"> <!-- this is the service object that we want to make transactional --> <bean id="fooService" class="x.y.service.DefaultFooService"/> <!-- the transactional advice (what 'happens'; see the <aop:advisor/> bean below) --> <tx:advice id="txAdvice" transaction-manager="txManager"> <!-- the transactional semantics... --> <tx:attributes> <!-- all methods starting with 'get' are read-only --> <tx:method name="get*" read-only="true"/> <!-- other methods use the default transaction settings (see below) --> <tx:method name="*"/> </tx:attributes> </tx:advice> <!-- ensure that the above transactional advice runs for any execution of an operation defined by the FooService interface --> <aop:config> <aop:pointcut id="fooServiceOperation" expression="execution(* x.y.service.FooService.*(..))"/> <aop:advisor advice-ref="txAdvice" pointcut-ref="fooServiceOperation"/> </aop:config> <!-- don't forget the DataSource --> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/> <property name="url" value="jdbc:oracle:thin:@rj-t42:1521:elvis"/> <property name="username" value="scott"/> <property name="password" value="tiger"/> </bean> <!-- similarly, don't forget the PlatformTransactionManager --> <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"/> </bean> <!-- other <bean/> definitions here --> </beans>
对于回滚事务,我们可以指定:
<tx:advice id="txAdvice" transaction-manager="txManager"> <tx:attributes> <tx:method name="get*" read-only="true" rollback-for="NoProductInStockException"/> <tx:method name="*"/> </tx:attributes> </tx:advice>
上例显示的指出,对于NoProductInStockException,我们做回滚处理。此外<tx:method/>可以对propagation isolation做相应的设定。
四)编程式事务管理
如果你要使用编程式的事务管理(适合少量需要事务管理的情形)。那么两个类可供你选择使用:TransactionTemplate 和 PlatformTransactionManager
1' TransactionTemplate
先是有返回值的情况:
public class SimpleService implements Service { // single TransactionTemplate shared amongst all methods in this instance private final TransactionTemplate transactionTemplate; // use constructor-injection to supply the PlatformTransactionManager public SimpleService(PlatformTransactionManager transactionManager) { Assert.notNull(transactionManager, "The 'transactionManager' argument must not be null."); this.transactionTemplate = new TransactionTemplate(transactionManager); } public Object someServiceMethod() { return transactionTemplate.execute(new TransactionCallback() { // the code in this method executes in a transactional context public Object doInTransaction(TransactionStatus status) { updateOperation1(); return resultOfUpdateOperation2(); } }); } }
无返回值的情况:
transactionTemplate.execute(new TransactionCallbackWithoutResult() { protected void doInTransactionWithoutResult(TransactionStatus status) { try { updateOperation1(); updateOperation2(); } catch (SomeBusinessExeption ex) { status.setRollbackOnly();//代码显示的强行进行rollback } } });
还可以进行一些属性的设置:
public class SimpleService implements Service { private final TransactionTemplate transactionTemplate; public SimpleService(PlatformTransactionManager transactionManager) { Assert.notNull(transactionManager, "The 'transactionManager' argument must not be null."); this.transactionTemplate = new TransactionTemplate(transactionManager); // the transaction settings can be set here explicitly if so desired this.transactionTemplate.setIsolationLevel(TransactionDefinition.ISOLATION_READ_UNCOMMITTED); this.transactionTemplate.setTimeout(30); // 30 seconds // and so forth... } }
2' PlatformTransactionManager
有之前声明式事务管理的介绍,相信将PlatformTransactionManager转换为编程式的事务管理就简单了:
DefaultTransactionDefinition def = new DefaultTransactionDefinition(); // explicitly setting the transaction name is something that can only be done programmatically def.setName("SomeTxName"); def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED); TransactionStatus status = txManager.getTransaction(def); try { // execute your business logic here } catch (MyException ex) { txManager.rollback(status); throw ex; } txManager.commit(status);
五) propagation和isolation
1' propagation
1、PROPAGATION_REQUIRED:如果存在一个事务,则支持当前事务。如果没有事务则开启。
2、PROPAGATION_SUPPORTS:如果存在一个事务,支持当前事务。如果没有事务,则非事务的执行。
3、PROPAGATION_MANDATORY:如果已经存在一个事务,支持当前事务。如果没有一个活动的事务,则抛出异常。
4、PROPAGATION_REQUIRES_NEW:总是开启一个新的事务。如果一个事务存在,则将这个存在的事务挂起。
5、PROPAGATION_NOT_SUPPORTED:总是非事务地执行,并挂起任何存在的事务。
6、PROPAGATION_NEVER:总是非事务地执行,如果存在一个活动事务,则抛出异常。
7、PROPAGATION_NESTED:如果一个活动的事务存在,则运行在一个嵌套的事务中,如果没有活动事务,则按TransactionDefinition.PROPAGATION_REQUIRED属性执行
2' isolation
1、ISOLATION_DEFAULT: 这是一个PlatfromTransactionManager默认的隔离级别,使用数据库默认的事务隔离级别。
2、ISOLATION_READ_UNCOMMITTED:这是事务最低的隔离级别,它允许另外一个事务可以看到这个事务未提交的数据。
3、ISOLATION_READ_COMMITTED:保证一个事务修改的数据提交后才能被另外一个事务读取。另外一个事务不能读取该事务未提交的数据。
4、ISOLATION_REPEATALBE_READ: 这种事务隔离级别可以防止脏读,不可重复读。但是可能出现幻想读。它除了保证一个事务不能读取另外一个事务未提交的数据外,还保证了避免下面的情况产生(不可重复读)。
5、ISOLATION_SERIALIZABLE 这是花费最高代价但是最可靠的事务隔离级别。事务被处理为顺序执行。除了防止脏读,不课重复读外,还避免了幻想读。
发表评论
-
Spring --- AOP IV
2012-12-21 16:44 996Spring AOP APIs 一)一个最简单的例子 publ ... -
Spring --- AOP III
2012-12-19 13:19 1076这篇文章先补充两个AOP的概念: 一)引入(Introduct ... -
Spring --- AOP II
2012-12-17 19:29 1227一)Spring AOP---schema-based ... -
Spring --- AOP
2012-12-13 16:10 1196一)什么是AOP AOP(A ... -
Spring --- SpEL
2012-12-11 16:10 9612一)什么是SpEL SpEL -- Spring Expr ... -
Spring --- Data Binding
2012-12-10 14:40 3133一) BeanWrapper BeanWrapper这个类 ... -
Spring --- Validation
2012-12-07 15:05 1877一) Validator接口 Spring的Validat ... -
Spring --- Resource
2012-12-06 16:50 1593一)如何使用spring中的r ... -
Spring --- IOC III
2012-12-04 15:34 1324承接上两篇IOC的介绍,我们继续... 9)Applicati ... -
Spring --- IOC II
2012-11-30 15:43 1580承接前一篇Spring --- IOC,继续IOC的介绍 6 ... -
Spring --- IOC
2012-11-28 16:36 1148一) IOC其实很简单 什么是IOC(控制反转)? 这名 ... -
开篇简介--Spring is not only Spring Framework
2012-03-06 16:42 1765一)什么是Spring 在java领域,当我们提起Spri ...
相关推荐
10. **spring-tx-3.2.0.RELEASE.jar**:事务管理模块提供了编程和声明式的事务管理,支持JTA(Java Transaction API)和本地事务。这使得在Spring应用中管理事务变得容易。 这组Spring 3.2.0库的完整集合,为开发者...
2. **事务管理(Transaction Management)**:Spring 提供了强大的事务管理功能,能够控制多个数据库操作是否作为一个事务进行。整合Struts 2 和Spring 后,我们可以在Spring 配置文件中定义事务规则,并让Spring ...
5. **Transaction Management**:MyBatis-Spring 提供了与 Spring 事务管理的无缝集成,可以使用 Spring 的声明式事务管理来处理数据操作的事务。 在实际项目中,mybatis-spring-1.3.3.jar 包的使用步骤通常包括...
Spring是什么呢?首先它是一个开源的项目,而且目前非常活跃...它实现了很优雅的MVC,对不同的数据访问技术提供了统一的接口,采用IOC使得可以很容易的实现bean的装配,提供了简洁的AOP并据此实现Transaction Management
2. **Transaction Management**: Spring-JDBC支持声明式事务管理,允许开发者使用注解(如@Transactional)来控制事务的边界,无需手动调用commit()和rollback()。这提高了代码的可读性和可维护性。 3. **...
这个jar包是Spring的事务管理模块,提供了声明式事务管理(Declarative Transaction Management)和编程式事务管理(Programmatic Transaction Management)。声明式事务管理是Spring的一大特色,通过在XML配置或...
2. **Transaction Management** Spring提供了声明式事务管理,允许开发者在配置文件中定义事务边界,而无需在代码中显式处理。源码中,你可以看到TransactionProxyFactoryBean和PlatformTransactionManager是如何...
5. **Transaction Management**: MyBatis-Spring 与 Spring 的事务管理器集成,支持声明式事务管理。这意味着你可以利用 Spring 的事务注解(如 @Transactional)来控制事务边界,而无需在 DAO 层手动管理事务。 6....
5. **事务管理(Transaction Management)**:Spring提供了一种统一的方式来管理事务,无论是编程式还是声明式,都能在不同的事务API之间无缝切换。 6. **Spring Boot**:Spring Boot简化了Spring应用的初始搭建...
2. **事务管理(Transaction Management)**:Spring提供了声明式事务管理,只需在配置文件中声明事务边界,无需在业务代码中手动控制事务的开启、提交和回滚。这种方式大大简化了事务处理,降低了出错的可能性。 3...
4. **Transaction Management**: MyBatis-Spring提供了Spring事务管理的支持,使得事务边界可以由Spring进行管理。这包括声明式事务和编程式事务,可以根据项目的具体需求选择适合的方式。 5. **ExecutorType**: 在...
5. **Transaction Management**:事务管理功能进一步完善,支持声明式事务处理,通过注解或者XML配置即可完成事务管理。 三、依赖解析 在"spring-framework-2.0-m1-with-dependencies.rar"中,包含了Spring框架...
51.3. Configuring Management-specific SSL 51.4. Customizing the Management Server Address 51.5. Disabling HTTP Endpoints 52. Monitoring and Management over JMX 52.1. Customizing MBean Names 52.2. ...
此外,它还提供了Transaction Management API,用于处理跨多个数据库操作的事务。 4. **Web MVC**: Spring的Model-View-Controller(MVC)框架是构建Web应用的首选,它提供了一种解耦的方式处理请求和响应。4.3.6...
5. **Transaction Management**:Spring 提供了声明式和编程式的事务管理,使开发者可以轻松地控制事务边界。 6. **Bean 自动装配(Auto-Wiring)**:Spring 可以自动识别并连接容器中的 Bean,根据类型或名称进行...
5. **Transaction Management:** MyBatis-Spring 提供了基于 Spring 的事务管理。在 1.2.2 版本中,你可以利用 Spring 的声明式事务管理,只需在服务层的方法上添加 @Transactional 注解,就可以自动开启和提交...
6. **JMX(Java Management Extensions)集成**:Spring 3.0 提供了对 JMX 的全面支持,使应用程序的管理更加便捷,可以监控和管理应用的运行状态。 7. **Spring Expression Language (SpEL)**:Spring 3.0 引入的 ...
Framework supports declarative transaction management, remote access to your logic through RMI or web services, and various options for persisting your data. It offers a full-featured MVC framework, ...
4. **JMX改进**:增强了JMX(Java Management Extensions)的集成,便于管理和监控Spring应用。 5. **错误处理**:改进了错误和异常处理机制,使得问题定位更为方便。 三、Spring主要模块 1. **Core Container**:...