首页 > 学院 > 开发设计 > 正文

Spring(九)Spring对事务的支持

2019-11-14 23:44:59
字体:
来源:转载
供稿:网友
SPRing(九)Spring对事务的支持一、对事务的支持

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

Spring管理事务方式:

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

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

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

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

二、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.ClassPathXmlapplicationContext;import 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) {    ClassPathXmlApplicationContext cpx=new ClassPathXmlApplicationContext("applicationContext.xml");        //获取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.ClassPathXmlApplicationContext;import 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) {        ClassPathXmlApplicationContext cpx = new ClassPathXmlApplicationContext(                "applicationContext.xml");        // 获取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、编程事务配置
<?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"    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.ClassPathXmlApplicationContext;import com.pb.dao.PersonDao;import com.pb.entity.Person;public class FirstAOPTransationDemo {    public static void main(String[] args) {        ClassPathXmlApplicationContext cpx=new ClassPathXmlApplicationContext("applicationContext.xml");            //这里调用代理的类        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.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:p="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后声明式事务管理:基于XMLSchema

步骤:

  1. 加入相关的XML命名空间
  2. 使用<tx:advice>标签指定Advice
  3. 使用<aop:config>标签配置事务管理
<?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-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;    }}

配置文件中加入一条

<?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-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>


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表