Spring事务管理

Spring事务管理方式

JDBC编程事务管理 可以清楚地控制事务的边界,事务控制粒度细化(编程的方式)
JDBC声明事务管理
事务相关API不用介入程序之中,将事务管理与实际业务代码解耦(配置xml的方式)
  • JDBC编程事务管理


1.JDBC编程事务管理
实现 PlatflormTransactionManager接口
使用事务模版 TransactionTemplate


1.1使用PlatformTransactionManager管理事务大致流程
1>指定PlatformTransactionManager的实现类
2>定义事务属性TransactionDefinition
3>将事务定义传送给TransactionStatus
4>将欲进行的事务用try...catch语句封起来
5>如果事务出错,调用PlatformTransactionManager的rollback方法
示例代码:
Spring配置

<!-- 定义事务管理类 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
 <property name="dataSource" ref="dataSource"></property>
</bean>

Java代码
/**
  * 初始化事务
  */
 ClassPathXmlApplicationContext cpx=new ClassPathXmlApplicationContext("applicationContext.xml");
 PlatformTransactionManager ptm=(PlatformTransactionManager) cpx.getBean("transactionManager");
 DefaultTransactionDefinition dtd=new DefaultTransactionDefinition();
 dtd.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
 TransactionStatus ts=ptm.getTransaction(dtd);
 
 /*
  * 进行事务
  */
 try{
 DataSource ds=(DataSource) cpx.getBean("dataSource");
 JdbcTemplate jt=new JdbcTemplate(ds);
 jt.execute("insert into person values (1,'青龙','qinglong')");
 jt.execute("insert into person values (4,'白虎','baihu')");
 }
 catch(Exception e){
 ptm.rollback(ts);
 System.out.println(e.getMessage());
 }



1.2使用 TransactionTemplate  管理事务大致流程
1>需要封装一个 TransactionManager
2>创建事务回滚类
3>执行TransactionManager的 execute()方法


示例代码:

Spring配置
<!-- 定义事务管理类 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
 <property name="dataSource" ref="dataSource"></property>
</bean>
Java代码
/**
  * 初始化事务
  */
 ClassPathXmlApplicationContext cpx=new ClassPathXmlApplicationContext("applicationContext.xml");
 PlatformTransactionManager ptm=(PlatformTransactionManager) cpx.getBean("transactionManager");
 TransactionTemplate tt=new TransactionTemplate(ptm);
 DataSource ds=(DataSource) cpx.getBean("dataSource");
 final JdbcTemplate jt=new JdbcTemplate(ds);
 
 /**
  * 进行事务
  */
 tt.execute(
 new TransactionCallbackWithoutResult(){

 @Override
 protected void doInTransactionWithoutResult(
 TransactionStatus arg0) {
 jt.execute("insert into person values (1,'青龙','qinglong')");
 jt.execute("insert into person values (4,'白虎','baihu')");
 }

 
 }
 
 );



  • JDBC声明事务管理

2.声明式事务管理
2.1使用原始的 TransactionProxyFactoryBean
2.2使用 tx/aop命名空间配置
2.3使用注解@Transactional配置

2.1 使用原始的TransactionProxyFactoryBean
1>使用 TransactionProxyFactoryBean指定要介入的事务以及其方法
2>创建该Bean的实例,只要执行过程中抛出异常,就会自动回滚。

Spring配置
<!-- 定义Dao实现类 -->
 <bean id="personDao_target" class="com.spring.dao.PersonDaoImpl">
 <property name="dataSource" ref="dataSource"/> 
 </bean>
 <!-- 定义事务管理类 -->
 <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
 <property name="dataSource" ref="dataSource"></property>
 </bean>
 
 <!-- 指定事务代理bean -->
 <bean id="personDaoProxyBean" 
   class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
 <!-- 指定代理接口 -->
 <property name="proxyInterfaces">
 <list>
 <value>com.spring.dao.PersonDAO</value>
 </list>
 </property>
 <!-- 指定被代理的bean -->
 <property name="target" ref="personDao_target"/>
 <!-- 注入事务管理 -->
 <property name="transactionManager" ref="transactionManager"></property>
 <!-- 事务管理被代理Bean的具体方法以及方式 -->
 <property name="transactionAttributes">
 <props>
 <prop key="batch*">PROPAGATION_REQUIRED</prop>
 </props>
 </property>
 </bean>



Java代码
ClassPathXmlApplicationContext cpx=new ClassPathXmlApplicationContext("applicationContext.xml");
 PersonDAO personDao=(PersonDAO) cpx.getBean("personDaoProxyBean");
 
 Person p1=new Person();
 Person p2=new Person();
 p1.setId((long)8);
 p1.setName("青龙");
 p1.setPassword("qinglong");
 
 p2.setId((long)9);
 p2.setName("白虎");
 p2.setPassword("baihu ");
 List persons=new ArrayList();
 persons.add(p1);
 persons.add(p2);
 personDao.batchInsert(persons);
 System.out.println("执行完毕");



2.2使用tx/aop命名空间配置
1>在配置文件中引入tx、aop命名空间的声明
2>在Spring配置文件中定义事务类,业务类,事务管理类
3>在Spring配置文件中定义切面事件,指定切点事件,定义事务引用
4>实例化目标Bean,被拦截的方法

Spring配置
<?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:p="http://www.springframework.org/schema/p"
 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-2.0.xsd
 http://www.springframework.org/schema/aop
 http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
 http://www.springframework.org/schema/tx
 http://www.springframework.org/schema/tx/spring-tx-2.0.xsd
 ">

 <!-- 声明式事务管理,基于XML Schema:tx/aop******************************************************************************** -->
<!-- 定义Dao实现类 -->
 <bean id="personDao_target" class="com.spring.dao.PersonDaoImpl">
 <property name="dataSource" ref="dataSource"/> 
 </bean>
 <!-- 定义事务管理类 -->
 <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
 <property name="dataSource" ref="dataSource"></property>
 </bean>
 
 <!-- 定义事务类 -->
 <tx:advice id="txAdvice" transaction-manager="transactionManager">
 <tx:attributes>
<!-- 对以batch开头的方法进行事务管理 -->
 <tx:method name="batch*" propagation="REQUIRED"/>
 </tx:attributes>
 </tx:advice>
 
 <!-- aop配置,通过织入式编程,当目标方法执行的时候,切点的事件触发,则相应的事务管理代理执行-->
 <aop:config>
 <!-- 定义切点事件,指定拦截的方法,* 为所有方法 -->
 <aop:pointcut id="personDaoPc" expression="execution(* com.spring.dao.PersonDAO.*(..))" />
 <!-- 定义事务引用,以及切点事件引用,当切点触发的时候,进行事务管理 -->
 <aop:advisor advice-ref="txAdvice" pointcut-ref="personDaoPc"/>
 </aop:config>
</beans>
Java代码
ClassPathXmlApplicationContext cpx=new ClassPathXmlApplicationContext("Schema_applicationContext.xml");
 PersonDAO personDao=(PersonDAO) cpx.getBean("personDao_target");
 
 Person p1=new Person();
 Person p2=new Person();
 p1.setId((long)10);
 p1.setName("青龙");
 p1.setPassword("qinglong");
 
 p2.setId((long)11);
 p2.setName("白虎");
 p2.setPassword("baihu ");
 List persons=new ArrayList();
 persons.add(p1);
 persons.add(p2);
 personDao.batchInsert(persons);
 System.out.println("执行完毕");



2.3使用@Transactional注解配置
1>在配置文件中引入tx命名空间的声明
2> 在业务类中标注@Transaction注解
3>定义在Spring配置文件中定义业务类、事务管理类、事务管理驱动类
4>实例化目标Bean,被拦截的方法

Spring配置
<?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:p="http://www.springframework.org/schema/p"
 xmlns:tx="http://www.springframework.org/schema/tx"
 xsi:schemaLocation="http://www.springframework.org/schema/beans 
 http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
 http://www.springframework.org/schema/tx
 http://www.springframework.org/schema/tx/spring-tx-2.0.xsd
 "
 >

 <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
 <property name="driverClassName">
 <value>oracle.jdbc.driver.OracleDriver</value>
 </property>
 <property name="url">
 <value>jdbc:oracle:thin:@10.0.0.11:1521:orcl</value>
 </property>
 <property name="username">
 <value>demo</value>
 </property>
 <property name="password">
 <value>demo</value>
 </property>
 </bean>
 <!-- 业务类,由于该Bean实现类标注@Transactional,所以会被注解驱动自动织入事务管理增强 -->
 <bean id="personDao" class="demo.spring.dao.PersonDaoImpl">
 <property name="dataSource"  ref="dataSource"/>
 </bean>
 <!-- 事务管理类 --> 
 <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
 <property name="dataSource" ref="dataSource" />
 </bean>
 <!-- 事务管理驱动,对标注@Transaction注解的Bean进行加工处理,以织入事务管理切面 -->
 <tx:annotation-driven transaction-manager="transactionManager"/>
</beans>
Java代码
package com.spring.dao;

import java.util.Iterator;
import java.util.List;
import javax.sql.DataSource;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import com.spring.entity.Person;

@Transactional
public class PersonDaoImpl implements PersonDAO {

 private JdbcTemplate jt;

 public void setDataSource(DataSource dataSource){
 jt = new JdbcTemplate(dataSource);
 }
 
 public void insert(long id, String name,String password) { 

 jt.update("insert into person values(" + id +",'" + name +  "','" + password + "')");
 }
 
 @Transactional(propagation = Propagation.REQUIRED)
 public void batchInsert(List persons) { 
 for(Iterator it = persons.iterator();it.hasNext();){
 Person p = (Person) it.next();
 insert(p.getId(),p.getName(),p.getPassword());
 }
 }
}
ClassPathXmlApplicationContext cpx=new ClassPathXmlApplicationContext("annotation_applicationContext.xml");
 PersonDAO personDao=(PersonDAO) cpx.getBean("personDao_target");
 
 Person p1=new Person();
 Person p2=new Person();
 p1.setId((long)3);
 p1.setName("青龙");
 p1.setPassword("qinglong");
 
 p2.setId((long)5);
 p2.setName("白虎");
 p2.setPassword("baihu ");
 List persons=new ArrayList();
 persons.add(p1);
 persons.add(p2);
 personDao.batchInsert(persons);
 System.out.println("执行完毕");
ClassPathXmlApplicationContext cpx=new ClassPathXmlApplicationContext("annotation_applicationContext.xml");
 PersonDAO personDao=(PersonDAO) cpx.getBean("personDao_target");
 
 Person p1=new Person();
 Person p2=new Person();
 p1.setId((long)3);
 p1.setName("青龙");
 p1.setPassword("qinglong");
 
 p2.setId((long)5);
 p2.setName("白虎");
 p2.setPassword("baihu ");
 List persons=new ArrayList();
 persons.add(p1);
 persons.add(p2);
 personDao.batchInsert(persons);
 System.out.println("执行完毕");





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值