Spring-jdbc-事务处理详解及案例<五>

问题?Spring-jdbc-处理事务详解及案例

首先我们要想到spring以及把jdbc很多事儿都做了,为什么还要事务呢?

事务包括事务的提交及回滚,加入当我们进行数据交互的时候,数据发生错误,不允许出现事务被修改了,那么我们就要实现事务回滚的操作。


必须加的jar包



首先是在applicationContext.xml配置文件中声明事务

spring声明式事务处理
   spring
   声明:针对的是程序员,程序员告诉spring容器,哪些方法需要事务,哪些方法不需要事务(就比如为我们在hibernate中增、删、改就需要事务,而查就不需要事务了)

   事务处理   spring容器来做事务处理
  目的:让spring管理事务,开发者不再关注事务


那么久会呈现出下面这种状态:




那么我们的事务又怎么获得呢!在这里我们就需要一个得到事务的接口类了

PlatFormTransactionManage接口




spring声明式事务处理的步骤:
   1、搭建环境
   2、把dao层和service层的接口和类写完
   3、在spring的配置文件中,先导入dataSource
   4、测试
   5、导入dao和service层的bean
   6、测试
   7、进行AOP的配置
       1、引入事务管理器
       2、进行aop的配置
   8、测试service层的类看是否是代理对象



程序员做的事儿:在spring容器中,引入注入,及引入数据源

spring容器做的事儿:就是事务的声明,事务的启动,切面的通知


案例:

bean类:

package cn.itcast.sh.spring.domain;

public class Person {
	private Long pid;
	private String pname;
	private String psex;
	public Long getPid() {
		return pid;
	}
	public void setPid(Long pid) {
		this.pid = pid;
	}
	public String getPname() {
		return pname;
	}
	public void setPname(String pname) {
		this.pname = pname;
	}
	public String getPsex() {
		return psex;
	}
	public void setPsex(String psex) {
		this.psex = psex;
	}
	@Override
	public String toString() {
		return "Person [pid=" + pid + ", pname=" + pname + ", psex=" + psex
				+ "]";
	}
	
}

Dao层

package cn.itcast.sh.spring.dao;

import java.util.List;

import cn.itcast.sh.spring.domain.Person;

public interface PersonDao {
	public void savePerson();
	public List<Person> getPerson();
}

package cn.itcast.sh.spring.dao;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;

import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.support.JdbcDaoSupport;

import cn.itcast.sh.spring.domain.Person;

public class PersonDaoImpl extends JdbcDaoSupport implements PersonDao{

	public void savePerson() {
		this.getJdbcTemplate().update("insert into person(pname,psex) values('sss1','sss1')");
		
	}

	public List<Person> getPerson() {
		return this.getJdbcTemplate().query("select *from person", new RowMapper() {
			public Object mapRow(ResultSet arg0, int arg1) throws SQLException {
				Person person = new Person();
				person.setPid(arg0.getLong("pid"));
				person.setPname(arg0.getString("pname"));
				person.setPsex(arg0.getString("psex"));
				return person;
			}
		});
	}

}

service层

package cn.itcast.sh.spring.service;

import java.util.List;

import cn.itcast.sh.spring.domain.Person;

public interface PersonService {
	public void savePerson();
	public List<Person> getPerson();
}

package cn.itcast.sh.spring.service;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;

import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.support.JdbcDaoSupport;
import org.springframework.transaction.PlatformTransactionManager;

import cn.itcast.sh.spring.dao.PersonDao;
import cn.itcast.sh.spring.domain.Person;

public class PersonServiceImpl implements PersonService{
	private PersonDao personDao;
	
	public PersonDao getPersonDao() {
		return personDao;
	}

	public void setPersonDao(PersonDao personDao) {
		this.personDao = personDao;
	}

	
	
	public void savePerson() {
		//这就是spring要利用的事务接口,这个很重要,只要涉及事务就必须有它
		//PlatformTransactionManager
//		int i=1/0;
		//测试事务回滚:
		
		this.personDao.savePerson();
	}

	public List<Person> getPerson() {
		return this.personDao.getPerson();
	}


}


异常切面类:

<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	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.5.xsd
		http://www.springframework.org/schema/aop 
		http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
		http://www.springframework.org/schema/tx 
		http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
	<bean
		class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
		<property name="locations">
			<value>classpath:jdbc.properties</value>
		</property>
	</bean>
	
	<!-- 创建数据源 -->
	<bean id="dataSource" destroy-method="close"
		class="org.apache.commons.dbcp.BasicDataSource">
		<property name="driverClassName" value="${jdbc.driverClassName}" />
		<property name="url" value="${jdbc.url}" />
		<property name="username" value="${jdbc.username}" />
		<property name="password" value="${jdbc.password}" />
	</bean>
	
	<!-- dao层  事务层用到数据源datasource:增删改查-->
	<bean id="personDao" class="cn.itcast.sh.spring.dao.PersonDaoImpl">
		<property name="dataSource">
			<ref bean="dataSource"/>
		</property>
	</bean>
	
	<!-- service层 -->
	
	<bean id="personService" class="cn.itcast.sh.spring.service.PersonServiceImpl">
		<property name="personDao">
			<ref bean="personDao"/>
		</property>
	</bean>
	
	<!-- 异常切面 -->
	<bean id="exception" class="cn.itcast.sh.spring.exception.MyException"></bean>
	
	<!-- 创建事务管理器 :用到数据源datasource,起事务-->
	<bean id="transactionManager1" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource"><!-- 注入数据源对象 -->
			<ref bean="dataSource"/>
		</property>
	</bean>
	<!-- 创建事务管理器的对像名必须和下面,下面的通知transaction-manager=""相同 -->
	<!-- 通知:
			1、告诉spring容器,采用什么样的方法来处理事务
				(这里采取的是jdbc的DataSourceTransactionManager的方式,
										当然也有hibernate的事务)
			2、高数spring容器,采取什么样的事务策略
	 -->
	 <tx:advice id="tx" transaction-manager="transactionManager1">
	 	<tx:attributes>
	 		<!--
	 			name:规定方法的
	 			isolation:数据库隔离机制   默认值DEFAULT
	 			propagation:传播机制(属性)默认值REQUIRED
	 			所以这两个属性不用写,直接就是默认值
	 		 -->
	 		<tx:method name="save*" isolation="DEFAULT" propagation="REQUIRED" read-only="false"/>
	 	</tx:attributes>
	 </tx:advice>
	 
	 <aop:config>
	 	<aop:pointcut expression="execution(* cn.itcast.sh.spring.service.*.*(..))" id="perfram"/>
	 	<aop:advisor advice-ref="tx" pointcut-ref="perfram"/>
	 	<aop:aspect ref="exception">
	 		<aop:after-throwing method="myException" throwing="ee" pointcut-ref="perfram"/>
	 	</aop:aspect>
	 </aop:config>
	
</beans>

jdbc.properies配置文件




applicationContext.xml配置文件

<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	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.5.xsd
		http://www.springframework.org/schema/aop 
		http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
		http://www.springframework.org/schema/tx 
		http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
	<bean
		class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
		<property name="locations">
			<value>classpath:jdbc.properties</value>
		</property>
	</bean>
	
	<!-- 创建数据源 -->
	<bean id="dataSource" destroy-method="close"
		class="org.apache.commons.dbcp.BasicDataSource">
		<property name="driverClassName" value="${jdbc.driverClassName}" />
		<property name="url" value="${jdbc.url}" />
		<property name="username" value="${jdbc.username}" />
		<property name="password" value="${jdbc.password}" />
	</bean>
	
	<!-- dao层  事务层用到数据源datasource:增删改查-->
	<bean id="personDao" class="cn.itcast.sh.spring.dao.PersonDaoImpl">
		<property name="dataSource">
			<ref bean="dataSource"/>
		</property>
	</bean>
	
	<!-- service层 -->
	
	<bean id="personService" class="cn.itcast.sh.spring.service.PersonServiceImpl">
		<property name="personDao">
			<ref bean="personDao"/>
		</property>
	</bean>
	
	<!-- 异常切面 -->
	<bean id="exception" class="cn.itcast.sh.spring.exception.MyException"></bean>
	
	<!-- 创建事务管理器 :用到数据源datasource,起事务-->
	<bean id="transactionManager1" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource"><!-- 注入数据源对象 -->
			<ref bean="dataSource"/>
		</property>
	</bean>
	<!-- 创建事务管理器的对像名必须和下面,下面的通知transaction-manager=""相同 -->
	<!-- 通知:
			1、告诉spring容器,采用什么样的方法来处理事务
				(这里采取的是jdbc的DataSourceTransactionManager的方式,
										当然也有hibernate的事务)
			2、高数spring容器,采取什么样的事务策略
	 -->
	 <tx:advice id="tx" transaction-manager="transactionManager1">
	 	<tx:attributes>
	 		<!--
	 			name:规定方法的
	 			isolation:数据库隔离机制   默认值DEFAULT
	 			propagation:传播机制(属性)默认值REQUIRED
	 			所以这两个属性不用写,直接就是默认值
	 		 -->
	 		<tx:method name="save*" isolation="DEFAULT" propagation="REQUIRED" read-only="false"/>
	 	</tx:attributes>
	 </tx:advice>
	 
	 <aop:config>
	 	<aop:pointcut expression="execution(* cn.itcast.sh.spring.service.*.*(..))" id="perfram"/>
	 	<aop:advisor advice-ref="tx" pointcut-ref="perfram"/>
	 	<aop:aspect ref="exception">
	 		<aop:after-throwing method="myException" throwing="ee" pointcut-ref="perfram"/>
	 	</aop:aspect>
	 </aop:config>
	
</beans>

测试类:


package cn.itcast.sh.spring.test;

import javax.sql.DataSource;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import cn.itcast.sh.spring.dao.PersonDao;
import cn.itcast.sh.spring.service.PersonService;

public class TransactionTest {
	public static ApplicationContext applicationContext;
	static{
		applicationContext=new ClassPathXmlApplicationContext("cn/itcast/sh/spring/transaction/applicationContext.xml");
	}
	
	//测试datasource(JDBC)
	@Test
	public void transaction(){
		DataSource dataSource = (DataSource)applicationContext.getBean("dataSource");
		System.out.println("datasource  "+dataSource);
	}
	
	//测试dao层
	@Test
	public void persondao(){
		PersonDao personDao = (PersonDao)applicationContext.getBean("personDao");
		System.out.println("dao层dataSource  "+personDao);
	}
	//测试service层
	@Test
	public void personService(){
		PersonService personService = (PersonService)applicationContext.getBean("personService");
		System.out.println("Service  "+personService);
		personService.savePerson();//测试及测试事务回滚
	}
}


spring中所需要的知识点及学习方向文档


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值