Java事务的类型有三种:
JDBC事务、 可以将多个 SQL 语句结合到一个事务中。JDBC 事务的一个缺点是事务的范围局限于一个数据库连接。一个 JDBC 事务不能跨越多个数据库
JTA(Java Transaction API)事务、事务可以跨越多个数据库或多个DAO,使用也比较复杂。
容器事务。主要指的是J2EE应用服务器提供的事务管理,局限于EJB应用使用。
spring事务的配置方式编程式事务和声明式事务,相信大家都知道是有5种,但我们经常使用的应该就是基于注解和tx标签配置拦截器两种方式了
1
2
3
4
5
6
7
8
9
10
|
< bean id = "sessionFactory" class = "org.springframework.orm.hibernate3.LocalSessionFactoryBean" > < property name = "configLocation" value = "classpath:hibernate.cfg.xml" /> < property name = "configurationClass" value = "org.hibernate.cfg.AnnotationConfiguration" /> </ bean > <!-- 定义事务管理器(声明式的事务) --> < bean id = "transactionManager" class = "org.springframework.orm.hibernate3.HibernateTransactionManager" > < property name = "sessionFactory" ref = "sessionFactory" /> </ bean > |
ps:声明式事务管理建立在AOP之上的。其本质是对方法前后进行拦截,然后在目标方法开始之前创建或者加入一个事务,在执行完目标方法之后根据执行情况提交或者回滚事务。
1、基于注解,DAO上需加上@Transactional注解
1
|
< tx:annotation-driven transaction-manager = "transactionManager" /> |
2、使用tx标签配置的拦截器
1
2
3
4
5
6
7
8
9
10
11
12
|
< tx:advice id = "txAdvice" transaction-manager = "transactionManager" > < tx:attributes > < tx:method name = "*" propagation = "REQUIRED" /> </ tx:attributes > </ tx:advice > < aop:config > < aop:pointcut id = "interceptorPointCuts" expression = "execution(* com.bluesky.spring.dao.*.*(..))" /> < aop:advisor advice-ref = "txAdvice" pointcut-ref = "interceptorPointCuts" /> </ aop:config > |
3、使用拦截器
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
< bean id = "transactionInterceptor" class = "org.springframework.transaction.interceptor.TransactionInterceptor" > < property name = "transactionManager" ref = "transactionManager" /> <!-- 配置事务属性 --> < property name = "transactionAttributes" > < props > < prop key = "*" >PROPAGATION_REQUIRED</ prop > </ props > </ property > </ bean > < bean class = "org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator" > < property name = "beanNames" > < list > < value >*Dao</ value > </ list > </ property > < property name = "interceptorNames" > < list > < value >transactionInterceptor</ value > </ list > </ property > </ bean > |
4、所有Bean共享一个代理基类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
< bean id = "transactionBase" class = "org.springframework.transaction.interceptor.TransactionProxyFactoryBean" lazy-init = "true" abstract = "true" > <!-- 配置事务管理器 --> < property name = "transactionManager" ref = "transactionManager" /> <!-- 配置事务属性 --> < property name = "transactionAttributes" > < props > < prop key = "*" >PROPAGATION_REQUIRED</ prop > </ props > </ property > </ bean > <!-- 配置DAO --> < bean id = "userDaoTarget" class = "com.bluesky.spring.dao.UserDaoImpl" > < property name = "sessionFactory" ref = "sessionFactory" /> </ bean > < bean id = "userDao" parent = "transactionBase" > < property name = "target" ref = "userDaoTarget" /> </ bean > |
5、每个Bean都有一个代理
1
2
3
4
5
6
7
8
9
10
11
12
13
|
< bean id = "userDao" class = "org.springframework.transaction.interceptor.TransactionProxyFactoryBean" > <!-- 配置事务管理器 --> < property name = "transactionManager" ref = "transactionManager" /> < property name = "target" ref = "userDaoTarget" /> < property name = "proxyInterfaces" value = "com.bluesky.spring.dao.GeneratorDao" /> <!-- 配置事务属性 --> < property name = "transactionAttributes" > < props > < prop key = "*" >PROPAGATION_REQUIRED</ prop > </ props > </ property > </ bean > |