你的位置:首页 > Java教程

[Java教程]Spring(九)Spring对事务的支持


一、对事务的支持

事务:是一组原子操作的工作单元,要么全部成功,要么全部失败

Spring管理事务方式:

  • JDBC编程事务管理:--可以控制到代码中的行

可以清楚的控制事务的边界,事务控制粒度化细(编程的方式

  • JDBC声明事务管理---可以控制到方法

事务相关API不用介入程序之中,将事务管理与实际业务代码解耦合(配置

 

 

二、JDBC编程事务管理

Spring提供两种方式实现编程式的事务管理:

  • 实现PlatformTransactionManager接口
  • 使用TransactionTemplate模式

2.1、实现PlatformTransactionManager接口

大致步骤:

  • 指定PlatformTransactionManager的实现类
  • 定义事务TransactionDefinition
  • 将事务定义传送给TransactionStatus
  • 将欲进行的事务用try..catch语句封起来
  • 如果事务出错,调用PlatformTransactionManager的rollback方法
package com.pb.transaction.demo;import javax.sql.DataSource;import org.springframework.context.support.ClassPathimport org.springframework.jdbc.core.JdbcTemplate;import org.springframework.transaction.PlatformTransactionManager;import org.springframework.transaction.TransactionStatus;import org.springframework.transaction.support.DefaultTransactionDefinition;/** * 使用TransactionManager事务管理 * 缺点:侵入代码 * 优点:控制度细粒度 */public class TransactionManagerDemo {    public static void main(String[] args) {  ClassPath=new ClassPath);    //获取platform对象  PlatformTransactionManager ptm=(PlatformTransactionManager) cpx.getBean("transactionManager");  //事务定义器  DefaultTransactionDefinition dtd=new DefaultTransactionDefinition();  //设置事务定义器的行为  dtd.setPropagationBehavior(DefaultTransactionDefinition.PROPAGATION_REQUIRED);  //事务状态通过事务管理器创建  TransactionStatus ts=ptm.getTransaction(dtd);    //进行事务    try {    //获取数据源    DataSource ds=(DataSource) cpx.getBean("dataSource");    //创建JDBCTemplacte    JdbcTemplate jt=new JdbcTemplate(ds);    //执行更新或者插入等操作    jt.update("insert into person values(11,'TTM',23)");    jt.update("update person set name='张王八' where id=7");    ptm.commit(ts);        System.out.println("===========");  } catch (Exception e) {    ptm.rollback(ts);    System.out.println("撤消=======");    e.printStackTrace();  }    }}

 

2.2、使用TransactionTemplate模式

 

大致步骤:

  • 需要封装一个TransactionManager
  • 创建事务回滚类
  • 执行TransactionManager的execute()方法
package com.pb.transaction.demo;import javax.sql.DataSource;import org.springframework.context.support.ClassPathimport org.springframework.jdbc.core.JdbcTemplate;import org.springframework.transaction.PlatformTransactionManager;import org.springframework.transaction.TransactionStatus;import org.springframework.transaction.support.DefaultTransactionDefinition;import org.springframework.transaction.support.TransactionCallback;import org.springframework.transaction.support.TransactionCallbackWithoutResult;import org.springframework.transaction.support.TransactionTemplate;/** * 使用TransactionTemplate事务管理 缺点:侵入代码 优点:控制度细粒度 */public class TransactionTeplateDemo {  public static void main(String[] args) {    ClassPath= new ClassPath"applicationContext.);    // 获取platform对象    PlatformTransactionManager ptm = (PlatformTransactionManager) cpx        .getBean("transactionManager");    // 事务模版    TransactionTemplate tt = new TransactionTemplate(ptm);    // 获取数据源    DataSource ds = (DataSource) cpx.getBean("dataSource");    // 创建JDBCTemplacte    final JdbcTemplate jt = new JdbcTemplate(ds);    // 进行事务回调函数    tt.execute(new TransactionCallbackWithoutResult() {      @Override      protected void doInTransactionWithoutResult(TransactionStatus arg0) {        // 执行更新或者插入等操作        jt.update("insert into person values(17,'TOM',23)");        jt.update("update person set name='李四3' where id=4");      }    });      }}

 

2.3、编程事务配置

<??><beans  ="http://www.springframework.org/schema/beans"  ="http://www.w3.org/2001/  ="http://www.springframework.org/schema/p"  xsi:schemaLocation="http://www.springframework.org/schema/beans   http://www.springframework.org/schema/beans/spring-beans-3.1.xsd"><!-- 声明数据源 org.springframework.jdbc.datasource.DriverManagerDataSource/com.mchange.v2.c3p0.ComboPooledDataSource-->          <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"><!--驱动 --><property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/><!--url --><property name="url" value="jdbc:oracle:thin:@localhost:1521:orcl"/><!--用户名 --><property name="username" value="accp"/><!--密码 --><property name="password" value="accp"/></bean><bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="dataSource"></property></bean></beans>

 

三、JDBC声明事务管理

主要通过AOP功能实现

不需要修改原有的类

使用TransationProxyFactoryBean指定要介入的事务以及方法

实体类:数据库中有与之相对应的表

package com.pb.entity;public class Person {  private Long id;  private String name;  private Integer age;  public Long getId() {    return id;  }  public void setId(Long id) {    this.id = id;  }  public String getName() {    return name;  }  public void setName(String name) {    this.name = name;  }  public Integer getAge() {    return age;  }  public void setAge(Integer age) {    this.age = age;  }    }

dao和实现类

package com.pb.dao;import java.util.List;import com.pb.entity.Person;public interface PersonDao {  public int insert(Person p);    public int batchInsert(List<Person> persons);  }//实现类package com.pb.dao.impl;import java.util.List;import javax.sql.DataSource;import org.springframework.jdbc.core.JdbcTemplate;import com.pb.dao.PersonDao;import com.pb.entity.Person;public class PersonDaoImpl implements PersonDao {  private JdbcTemplate jdbcTemplate;    public void setDataSource(DataSource ds){    jdbcTemplate=new JdbcTemplate(ds);  }  @Override  public int insert(Person p) {    String sql="insert into person values(?,?,?)";    Object [] params={p.getId(),p.getName(),p.getAge()};    return jdbcTemplate.update(sql,params);  }  @Override  public int batchInsert(List<Person> persons) {    int count=0;    for (Person person : persons) {      insert(person);      count++;    }    return count;  }}

测试类

package com.pb.transation.aop.demo;import java.util.ArrayList;import java.util.List;import org.springframework.context.support.ClassPathimport com.pb.dao.PersonDao;import com.pb.entity.Person;public class FirstAOPTransationDemo {  public static void main(String[] args) {    ClassPath=new ClassPath);      //这里调用代理的类    PersonDao personDao=(PersonDao) cpx.getBean("personDaoProxy");        Person p1=new Person();    p1.setId(new Long(28));    p1.setName("朱雀");    p1.setAge(199);    Person p2=new Person();    p2.setId(new Long(29));    p2.setName("玄武");    p2.setAge(150);    List<Person> persons=new ArrayList<Person>();    persons.add(p1);    persons.add(p2);    int count=personDao.batchInsert(persons);    System.out.println("更新了,"+count+"条记录");      }}

applicationContext.

<??><beans  ="http://www.springframework.org/schema/beans"  ="http://www.w3.org/2001/  ="http://www.springframework.org/schema/p"  xsi:schemaLocation="http://www.springframework.org/schema/beans   http://www.springframework.org/schema/beans/spring-beans-3.1.xsd"><!-- 声明数据源 org.springframework.jdbc.datasource.DriverManagerDataSource/com.mchange.v2.c3p0.ComboPooledDataSource-->          <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"><!--驱动 --><property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/><!--url --><property name="url" value="jdbc:oracle:thin:@localhost:1521:orcl"/><!--用户名 --><property name="username" value="accp"/><!--密码 --><property name="password" value="accp"/></bean><!--接口实现类 --><bean id="personDao" class="com.pb.dao.impl.PersonDaoImpl"><property name="dataSource" ref="dataSource"></property></bean><bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="dataSource"></property></bean><bean id="personDaoProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"><!--指定接口 --><property name="proxyInterfaces" ><list><value>com.pb.dao.PersonDao</value></list></property><!-- 管理的目标 --><property name="target" ref="personDao"/><!--注入事务管理 --><property name="transactionManager" ref="transactionManager"></property><!--事务管理的方法 和方式 --><property name="transactionAttributes"><props><prop key="batch*">PROPAGATION_REQUIRED</prop></props></property></bean></beans>

四、事务的属性

声明式事务以方法为边界,简单的讲,一个方法被看成一个事务

Spring中事务的属性:

  • 传播行为(Propagation Behavior)
  • 隔离级别(Lsolation Level)
  • 只读提示(Rean-only Hints)
  • 事务超时期限(The Transaction Timeout period)

4.1、传播行为

4.2、隔离级别

 

五、Spring2.0后声明式事务管理:基于

步骤:

  1. 加入相关的
  2. 使用<tx:advice>标签指定Advice
  3. 使用<aop:config>标签配置事务管理
<??><beans  ="http://www.springframework.org/schema/beans"  ="http://www.w3.org/2001/  ="http://www.springframework.org/schema/p"  ="http://www.springframework.org/schema/aop"  ="http://www.springframework.org/schema/tx"  xsi:schemaLocation="http://www.springframework.org/schema/beans   http://www.springframework.org/schema/beans/spring-beans-3.1.xsd  http://www.springframework.org/schema/aop  http://www.springframework.org/schema/aop/spring-aop-3.1.xsd  http://www.springframework.org/schema/tx  http://www.springframework.org/schema/tx/spring-tx-3.1.xsd"><!-- 声明数据源 org.springframework.jdbc.datasource.DriverManagerDataSource/com.mchange.v2.c3p0.ComboPooledDataSource-->          <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"><!--驱动 --><property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/><!--url --><property name="url" value="jdbc:oracle:thin:@localhost:1521:orcl"/><!--用户名 --><property name="username" value="accp"/><!--密码 --><property name="password" value="accp"/></bean><!--接口实现类 --><bean id="personDao" class="com.pb.dao.impl.PersonDaoImpl"><property name="dataSource" ref="dataSource"></property></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><tx:method name="batch*" propagation="REQUIRED"/></tx:attributes></tx:advice><aop:config><!--切入点 --><aop:pointcut expression="execution(* com.pb.dao.PersonDao.*(..) )" id="mypoint"/><!--关切入点和切入对象事务 --><aop:advisor advice-ref="txAdvice" pointcut-ref="mypoint"/></aop:config></beans>

六、基于注解的事务管理

package com.pb.dao.impl;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.pb.dao.PersonDao;import com.pb.entity.Person;//在要管理的类下加上@transactional@Transactionalpublic class PersonDaoImpl implements PersonDao {  private JdbcTemplate jdbcTemplate;    public void setDataSource(DataSource ds){    jdbcTemplate=new JdbcTemplate(ds);  }  @Override  public int insert(Person p) {    String sql="insert into person values(?,?,?)";    Object [] params={p.getId(),p.getName(),p.getAge()};    return jdbcTemplate.update(sql,params);  }  //在要管理的方法下加上属性propagation=Propagation.REQUIRED  @Transactional(propagation=Propagation.REQUIRED)  public int batchInsert(List<Person> persons) {    int count=0;    for (Person person : persons) {      insert(person);      count++;    }    return count;  }}

配置文件中加入一条

<??><beans  ="http://www.springframework.org/schema/beans"  ="http://www.w3.org/2001/  ="http://www.springframework.org/schema/p"  ="http://www.springframework.org/schema/aop"  ="http://www.springframework.org/schema/tx"  xsi:schemaLocation="http://www.springframework.org/schema/beans   http://www.springframework.org/schema/beans/spring-beans-3.1.xsd  http://www.springframework.org/schema/aop  http://www.springframework.org/schema/aop/spring-aop-3.1.xsd  http://www.springframework.org/schema/tx  http://www.springframework.org/schema/tx/spring-tx-3.1.xsd"><!-- 声明数据源 org.springframework.jdbc.datasource.DriverManagerDataSource/com.mchange.v2.c3p0.ComboPooledDataSource-->          <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"><!--驱动 --><property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/><!--url --><property name="url" value="jdbc:oracle:thin:@localhost:1521:orcl"/><!--用户名 --><property name="username" value="accp"/><!--密码 --><property name="password" value="accp"/></bean><!--接口实现类 --><bean id="personDao" class="com.pb.dao.impl.PersonDaoImpl"><property name="dataSource" ref="dataSource"></property></bean><!--事务管理的类 --><bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="dataSource"></property></bean><!--指明注解方式的事务管理器 --><tx:annotation-driven transaction-manager="transactionManager"/></beans>