一、对事务的支持
事务:是一组原子操作的工作单元,要么全部成功,要么全部失败
Spring管理事务方式:
可以清楚的控制事务的边界,事务控制粒度化细(编程的方式)
事务相关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后声明式事务管理:基于
步骤:
- 加入相关的
- 使用<tx:advice>标签指定Advice
- 使用<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>
原标题:Spring(九)Spring对事务的支持
关键词:Spring