spring支持
编程式事务控制和
声明式事务控制。
编程式事务控制:可以通过编程的方式来控制事务。
声明式事务控制:将事务控制和业务代码分离,只要通过xml或者注解即可实现。
spring事务的优点:
(1)为不同的API提供统一编程模型。
(2)为编程式事务管理提供简单的API而非复杂的的API。
(3)支持声明式事务管理。
(4)可以同多少数据库技术融合,如hibernate、JPA。
推荐使用事务:
大多使用声明式事务控制,因为这样可将事务和业务分离,虽然灵活性方面弱于编程式事务控制方式。
一、spring声明式事务
spring声明式事务有3部分组成:
DataSource(数据访问方式)、
TransactionManager、
代理机制。无论那种配置,一般DataSource和TransactionManager只会根据数据访问方式发生变化,如JPA的DataSource是EntityManager,TransactionManager是JpaTransctionManager。如图1.1事务配置所示,不同数据访问方式下的DataSource和TransactionManager。
图1.1 spring事务配置
根据代理机制的不同,spring事务的配置分为5种:
第一种方式:每个Bean都有一个代理
1 | <?xml version="1.0" encoding="UTF-8"?> |
2 | <beans xmlns="http://www.springframework.org/schema/beans" |
3 | xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" |
4 | xmlns:aop="http://www.springframework.org/schema/aop" |
5 | xsi:schemaLocation="http://www.springframework.org/schema/beans |
6 | http://www.springframework.org/schema/beans/spring-beans-2.5.xsd |
7 | http://www.springframework.org/schema/context |
8 | http://www.springframework.org/schema/context/spring-context-2.5.xsd |
9 | http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd"> |
10 |
|
11 | <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"> |
12 | <property name="configLocation" value="classpath:hibernate.cfg.xml" /> |
13 | <property name="configurationClass" value="org.hibernate.cfg.AnnotationConfiguration" /> |
14 | </bean> |
15 |
|
16 | <!-- 定义事务管理器(声明式的事务) --> |
17 | <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> |
18 | <property name="sessionFactory" ref="sessionFactory" /> |
19 | </bean> |
20 |
|
21 | <!-- 配置DAO --> |
22 | <bean id="userDaoTarget" class="com.bluesky.spring.dao.UserDaoImpl"> |
23 | <property name="sessionFactory" ref="sessionFactory" /> |
24 | </bean> |
25 |
|
26 | <bean id="userDao" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"> |
27 | <!-- 配置事务管理器 --> |
28 | <property name="transactionManager" ref="transactionManager" /> |
29 | <property name="target" ref="userDaoTarget" /> |
30 | <property name="proxyInterfaces" value="com.bluesky.spring.dao.GeneratorDao" /> |
31 | <!-- 配置事务属性 --> |
32 | <property name="transactionAttributes"> |
33 | <props> |
34 | <prop key="*">PROPAGATION_REQUIRED</prop> |
35 | </props> |
36 | </property> |
37 | </bean> |
38 | </beans> |
第二种方式:所有Bean共享一个代理基类
1 | ...... |
2 | <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"> |
3 | <property name="configLocation" value="classpath:hibernate.cfg.xml" /> |
4 | <property name="configurationClass" value="org.hibernate.cfg.AnnotationConfiguration" /> |
5 | </bean> |
6 |
|
7 | <!-- 定义事务管理器(声明式的事务) --> |
8 | <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> |
9 | <property name="sessionFactory" ref="sessionFactory" /> |
10 | </bean> |
11 |
|
12 | <bean id="transactionBase" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean" lazy-init="true" abstract="true"> |
13 | <!-- 配置事务管理器 --> |
14 | <property name="transactionManager" ref="transactionManager" /> |
15 | <!-- 配置事务属性 --> |
16 | <property name="transactionAttributes"> |
17 | <props> |
18 | <prop key="*">PROPAGATION_REQUIRED</prop> |
19 | </props> |
20 | </property> |
21 | </bean> |
22 |
|
23 | <!-- 配置DAO --> |
24 | <bean id="userDaoTarget" class="com.bluesky.spring.dao.UserDaoImpl"> |
25 | <property name="sessionFactory" ref="sessionFactory" /> |
26 | </bean> |
27 |
|
28 | <bean id="userDao" parent="transactionBase"> |
29 | <property name="target" ref="userDaoTarget" /> |
30 | </bean> |
第三种方式:使用拦截器
1 | ...... |
2 | <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"> |
3 | <property name="configLocation" value="classpath:hibernate.cfg.xml" /> |
4 | <property name="configurationClass" value="org.hibernate.cfg.AnnotationConfiguration" /> |
5 | </bean> |
6 |
|
7 | <!-- 定义事务管理器(声明式的事务) --> |
8 | <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> |
9 | <property name="sessionFactory" ref="sessionFactory" /> |
10 | </bean> |
11 |
|
12 | <bean id="transactionInterceptor" class="org.springframework.transaction.interceptor.TransactionInterceptor"> |
13 | <property name="transactionManager" ref="transactionManager" /> |
14 | <!-- 配置事务属性 --> |
15 | <property name="transactionAttributes"> |
16 | <props> |
17 | <prop key="*">PROPAGATION_REQUIRED</prop> |
18 | </props> |
19 | </property> |
20 | </bean> |
21 |
|
22 | <bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator"> |
23 | <property name="beanNames"> |
24 | <list> |
25 | <value>*Dao</value> |
26 | </list> |
27 | </property> |
28 | <property name="interceptorNames"> |
29 | <list> |
30 | <value>transactionInterceptor</value> |
31 | </list> |
32 | </property> |
33 | </bean> |
34 |
|
35 | <!-- 配置DAO --> |
36 | <bean id="userDao" class="com.bluesky.spring.dao.UserDaoImpl"> |
37 | <property name="sessionFactory" ref="sessionFactory" /> |
38 | </bean> |
第四种方式:使用tx标签配置的拦截器
1 | <?xml version="1.0" encoding="UTF-8"?> |
2 | <beans xmlns="http://www.springframework.org/schema/beans" |
3 | xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
4 | xmlns:context="http://www.springframework.org/schema/context" |
5 | xmlns:aop="http://www.springframework.org/schema/aop" |
6 | xmlns:tx="http://www.springframework.org/schema/tx" |
7 | xsi:schemaLocation="http://www.springframework.org/schema/beans |
8 | http://www.springframework.org/schema/beans/spring-beans-2.5.xsd |
9 | http://www.springframework.org/schema/context |
10 | http://www.springframework.org/schema/context/spring-context-2.5.xsd |
11 | http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd |
12 | http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd"> |
13 | <context:annotation-config /> |
14 | <context:component-scan base-package="com.bluesky" /> |
15 |
|
16 | <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"> |
17 | <property name="configLocation" value="classpath:hibernate.cfg.xml" /> |
18 | <property name="configurationClass" value="org.hibernate.cfg.AnnotationConfiguration" /> |
19 | </bean> |
20 |
|
21 | <!-- 定义事务管理器(声明式的事务) --> |
22 | <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> |
23 | <property name="sessionFactory" ref="sessionFactory" /> |
24 | </bean> |
25 |
|
26 | <tx:advice id="txAdvice" transaction-manager="transactionManager"> |
27 | <tx:attributes> |
28 | <tx:method name="*" propagation="REQUIRED" /> |
29 | </tx:attributes> |
30 | </tx:advice> |
31 |
|
32 | <aop:config> |
33 | <aop:pointcut id="interceptorPointCuts" expression="execution(* com.bluesky.spring.dao.*.*(..))" /> |
34 | <aop:advisor advice-ref="txAdvice" pointcut-ref="interceptorPointCuts" /> |
35 | </aop:config> |
36 | </bean> |
第五种方式:全注解
1 | ...... |
2 | <context:annotation-config /> |
3 | <context:component-scan base-package="com.bluesky" /> |
4 |
|
5 | <tx:annotation-driven transaction-manager="transactionManager" /> |
6 |
|
7 | <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"> |
8 | <property name="configLocation" value="classpath:hibernate.cfg.xml" /> |
9 | <property name="configurationClass" value="org.hibernate.cfg.AnnotationConfiguration" /> |
10 | </bean> |
11 |
|
12 | <!-- 定义事务管理器(声明式的事务) --> |
13 | <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> |
14 | <property name="sessionFactory" ref="sessionFactory" /> |
15 | </bean> |
此时在DAO上需加上@Transactional注解,如下:
1 | @Transactional |
2 | @Component("userDao") |
3 | publicclassUserDaoImplextendsHibernateDaoSupportimplementsUserDao { |
4 | publicList<User>listUsers() { |
5 | returnthis.getSession().createQuery("from User").list(); |
6 | } |
7 | ...... |
8 | } |
三、Spring事务的隔离级别(Isolation level)
1. ISOLATION_DEFAULT: 这是一个PlatfromTransactionManager默认的隔离级别,使用数据库默认的事务隔离级别。
另外四个与JDBC的隔离级别相对应。
2. ISOLATION_READ_UNCOMMITTED: 这是事务最低的隔离级别,它充许令外一个事务可以看到这个事务未提交的数据。
这种隔离级别会产生脏读,不可重复读和幻像读。
3. ISOLATION_READ_COMMITTED: 保证一个事务修改的数据提交后才能被另外一个事务读取。另外一个事务不能读取该事务未提交的数据。
4. ISOLATION_REPEATABLE_READ: 这种事务隔离级别可以防止脏读,不可重复读。但是可能出现幻像读。
它除了保证一个事务不能读取另一个事务未提交的数据外,还保证了避免下面的情况产生(不可重复读)。
5. ISOLATION_SERIALIZABLE这 是花费最高代价但是最可靠的事务隔离级别。事务被处理为顺序执行。
四、spring事务的传播特性
事务的几种传播特性
1. PROPAGATION_REQUIRED: 如果存在一个事务,则支持当前事务。如果没有事务则开启
2. PROPAGATION_SUPPORTS: 如果存在一个事务,支持当前事务。如果没有事务,则非事务的执行
3. PROPAGATION_MANDATORY: 如果已经存在一个事务,支持当前事务。如果没有一个活动的事务,则抛出异常。
4. PROPAGATION_REQUIRES_NEW: 总是开启一个新的事务。如果一个事务已经存在,则将这个存在的事务挂起。
5. PROPAGATION_NOT_SUPPORTED: 总是非事务地执行,并挂起任何存在的事务。
6. PROPAGATION_NEVER: 总是非事务地执行,如果存在一个活动事务,则抛出异常
7. PROPAGATION_NESTED:如果一个活动的事务存在,则运行在一个嵌套的事务中. 如果没有活动事务,
1. PROPAGATION_REQUIRED: 如果存在一个事务,则支持当前事务。如果没有事务则开启
2. PROPAGATION_SUPPORTS: 如果存在一个事务,支持当前事务。如果没有事务,则非事务的执行
3. PROPAGATION_MANDATORY: 如果已经存在一个事务,支持当前事务。如果没有一个活动的事务,则抛出异常。
4. PROPAGATION_REQUIRES_NEW: 总是开启一个新的事务。如果一个事务已经存在,则将这个存在的事务挂起。
5. PROPAGATION_NOT_SUPPORTED: 总是非事务地执行,并挂起任何存在的事务。
6. PROPAGATION_NEVER: 总是非事务地执行,如果存在一个活动事务,则抛出异常
7. PROPAGATION_NESTED:如果一个活动的事务存在,则运行在一个嵌套的事务中. 如果没有活动事务,