spring事务&综合小实例

spring事务+综合小实例

  • 1.事务管理的核心接口
  • 2.事务相关接口
    • 2.1PlatformTransactionManager
    • 2.2TransactionDefinition
    • 2.3TransactionStatus
  • 3.基于注解方式配置
    • 3.1配置元素
    • 3.2例子
      • 3.2.1创建一个spring项目
      • 3.2.2创建Java文件
      • 3.2.3xml文件
      • 3.2.4运行结果
  • 4.总结

1.事务管理的核心接口

spring-tx-X.X.X.RELEASE.jar包中:
1.PlatformTransactionManager平台事务管理器
2.TransactionDefinition事务定义或描述对象
3.TransactionStatus事务状态。

2.事务相关接口

2.1PlatformTransactionManager

1.TransactionStatus getTransaction(@Nullable TransactionDefinition definition) throws TransactionException;
获取事务状态信息。
2.void commit(TransactionStatus status) throws TransactionException;
提交事务。
3.void rollback(TransactionStatus status) throws TransactionException;
回滚事务。

2.2TransactionDefinition

1.String getName();
获取事务对象名称。
2.int getIsolationLevel();
获取事务的隔离级别。
3.int getPropagationBehavior();
获取事务的传播行为。
4.int getTimeout();
获取超时时间。
5.boolean isReadOnly();
获取事务是否只读。

2.3TransactionStatus

1.void flush();
刷新事务。
2.boolean hasSavepoint();
获取是否存在保存点。
3.boolean isCompleted();
获取事务是否完成。
4.boolean isNewTransaction();
获取是否是新事务。
5.boolean isRollbackOnly();
获取事务是否回滚。
6.void setRollbackOnly();
设置事务回滚。

3.基于注解方式配置

3.1配置元素

spring事务&综合小实例_第1张图片

3.2例子

3.2.1创建一个spring项目

spring事务&综合小实例_第2张图片

3.2.2创建Java文件

spring事务&综合小实例_第3张图片

package aspect;

import java.text.SimpleDateFormat;
import java.util.Date;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

@Aspect
@Component("myAspect")
public class MyAspect {

	@Pointcut("execution(* dao.*+.*(..))")
	public void pointCutDao(){}
	
	@Pointcut("execution(* service.*+.*(..))")
	public void pointCutService(){}
	
	@Pointcut("execution(* service.*+.*(..))")
	public void pointCutTransaction(){}
	
	@Before("pointCutDao()")
	public void beforeDao(JoinPoint joinPoint){
		System.out.println("Dao     Info  "+showTime() + "[" + joinPoint.getSignature().getName()+ "]    before");
	}
	
	@Before("pointCutService()")
	public void beforeService(JoinPoint joinPoint){
		System.out.println("Service Info  "+showTime() + "[" + joinPoint.getSignature().getName()+ "]    before");
	}
	
	@Before("pointCutTransaction()")
	public void beforeTransaction(JoinPoint joinPoint){
		System.out.println("Transaction Info  "+showTime() + "[" + joinPoint.getSignature().getName()+ "]    before");
	}
	
	@AfterReturning("pointCutDao()")
	public void afterReturnDao(JoinPoint joinPoint){
		System.out.println("Dao     Info  "+showTime() + "[" + joinPoint.getSignature().getName()+ "]    afterReturn");
	}
	
	@AfterReturning("pointCutService()")
	public void afterReturnService(JoinPoint joinPoint){
		System.out.println("Service Info  "+showTime() + "[" + joinPoint.getSignature().getName()+ "]    afterReturn");
	}
	
	@AfterReturning("pointCutTransaction()")
	public void afterReturnTransaction(JoinPoint joinPoint){
		System.out.println("Transaction Info  "+showTime() + "[" + joinPoint.getSignature().getName()+ "]    afterReturn");
	}
	
	private String showTime(){
		return "  "+new SimpleDateFormat("yyyy-mm-dd HH:mm:ss,s").format(new Date())+"  ";
	}
}

package client;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
import java.util.Set;

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

import service.PeopleService;
import domain.People;


public class Main {

	public static void main(String[] args) {
		Scanner scanner = new Scanner(System.in);
		@SuppressWarnings("resource")
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext(
				"resource/*.xml");
		PeopleService peopleService = (PeopleService) applicationContext.getBean("peopleService");
		
		//add 2 people,people scope is prototype
		People aPeople = (People) applicationContext.getBean("people");
		People bPeople = (People) applicationContext.getBean("people");
		//set people
		aPeople.setName("aPeople");
		aPeople.setAge(23);
		aPeople.setSex(0);
		bPeople.setName("bPeople");
		bPeople.setAge(32);
		bPeople.setSex(1);
		
		//add..
		List peoples = new ArrayList<>();
		peoples.add(aPeople);
		peoples.add(bPeople);
		
		//print peoples
		for(People people : peoples){
			System.out.println(people);
		}
		
		peoples = peopleService.batchAddPeople(peoples);
		
		//print peoples(with id)
		for(People people : peoples){
			System.out.println(people);
		}
		
		//update peoples   name : srcname+update
		for(People people : peoples){
			people.setName(people.getName()+"update");
		}
		
		//print updated peoples
		for(People people : peoples){
			System.out.println(people);
		}
		
		//update..
		peopleService.batchUpdPeople(peoples);
		
		//query all add peoples
		Map> queryPeoMap = peopleService.batchQuyPeople(peoples);
		
		//print query peoples
		Set set = queryPeoMap.keySet();
		Iterator iterator = set.iterator();
		while(iterator.hasNext()){
			People queryOnePeople = iterator.next();
			System.out.println("query:"+queryOnePeople);
			for(People queryResult : queryPeoMap.get(queryOnePeople)){
				System.out.println("result:"+queryResult);
			}
		}
		
		//delete id = 92(database has been)
		People delPeople = (People) applicationContext.getBean("people");
		delPeople.setId(Long.valueOf(92));
		
		//get peoples
		List delPeoples = new ArrayList<>();
		delPeoples.add(delPeople);
		
		
		//print delpeople
		for(People people : delPeoples){
			System.out.println(people);
		}
		
		//delete..
		delPeoples = peopleService.batchDelPeople(delPeoples);
		
		//print deleted peoples should equals srcdelpeoples
		for(People people : delPeoples){
			System.out.println(people);
		}
		
		//test Transaction all peoples age = srcage + 5 , sex = !sex
		peopleService.testTransaction();
		
	}

}

package dao;

import java.util.List;

import domain.People;

public interface PeopleDao {

	People addPeople(People people);
	
	People delPeople(People people);
	
	List queryPeople(People people);
	
	People updatePeople(People people);

	void testTransaction();
}

package daoimpl;

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

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import dao.PeopleDao;
import domain.People;

@Repository(value = "peopleDao")
public class PeopleDaoImpl implements PeopleDao{

	@Autowired
	private JdbcTemplate jdbcTemplate;
	
	private final String SELECT = "P.ID, P.NAME, P.AGE, P.SEX ";
	
	private final String TABLE = "PEOPLE P ";
	
	private final String SEQ_SQL = "SELECT SEQ_PEOPLE.NEXTVAL FROM DUAL ";
	
	private Long getSeq(){
		return (Long)this.jdbcTemplate.queryForObject(SEQ_SQL, new RowMapper() {
			@Override
			public Long mapRow(ResultSet rs, int arg1) throws SQLException {
				return Long.valueOf(rs.getLong("NEXTVAL"));
			}
		});
	}
	
	@Override
	public People addPeople(People people) {
		String insert_sql = "INSERT INTO " + TABLE + " ( " + SELECT
				+ ") VALUES(?,?,?,?)";
		people.setId(getSeq());
		this.jdbcTemplate.update(insert_sql, new Object[] { people.getId(),
				people.getName(), people.getAge(), people.getSex() },
				new int[] { Types.NUMERIC, Types.VARCHAR, Types.NUMERIC,
						Types.NUMERIC });
		return people;
	}

	@Override
	public People delPeople(People people) {
		String delete_sql = "DELETE FROM " + TABLE + " WHERE 1 = 1 "
				+ getCondition(people);
		this.jdbcTemplate.update(delete_sql);
		return people;
	}
	
	private String getCondition(People people){
		String condition = "";
		condition += people.getId() == null ? "" : " AND P.ID = " + people.getId();
		condition += people.getName() == null ? "" : " AND P.NAME = '" + people.getName()+"'";
		condition += people.getAge() == null ? "" : " AND P.AGE =   " + people.getAge();
		condition += people.getSex() == null ? "" : " AND P.SEX =   " + people.getSex();
		return condition;
	}
	
	@Override
	public List queryPeople(People people) {
		String select_sql = "SELECT " + SELECT + " FROM " + TABLE
				+ " WHERE 1 = 1 " + getCondition(people);
		return this.jdbcTemplate.query(select_sql,new PeopleRowMap());
	}

	@Override
	public People updatePeople(People people) {
		String update_sql = "UPDATE PEOPLE P SET ";
		//FIXME:if name == null ?
		update_sql += people.getName() == null ? "" : (" P.NAME = '"
				+ people.getName() + "',");
		update_sql += people.getAge() == null ? "" : (" P.AGE = "
				+ people.getAge() + ",");
		update_sql += people.getSex() == null ? "" : (" P.SEX = "
				+ people.getSex());
		update_sql += " WHERE P.ID = " + people.getId();
		this.jdbcTemplate.update(update_sql);
		return people;
	}

	public JdbcTemplate getJdbcTemplate() {
		return jdbcTemplate;
	}

	public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
		this.jdbcTemplate = jdbcTemplate;
	}
	
	@Override
	public void testTransaction(){
		this.jdbcTemplate.update("UPDATE PEOPLE P SET P.AGE = P.AGE + 5");
		int m = 1/0;
		this.jdbcTemplate.update("UPDATE PEOPLE P SET P.SEX = 1 - P.SEX");
	}
	
}
class PeopleRowMap implements RowMapper{

	@Override
	public People mapRow(ResultSet arg0, int arg1) throws SQLException {
		People people = new People();
		people.setId(arg0.getLong("ID"));
		if(arg0.getString("NAME") != null){
			people.setName(arg0.getString("NAME"));
		}
		people.setAge(arg0.getInt("AGE"));
		people.setSex(arg0.getInt("SEX"));
		return people;
	}
	
} 

package domain;

import java.io.Serializable;

import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

@Component(value = "people")
@Scope("prototype")
public class People implements Serializable{

	/**
	 * 
	 */
	private static final long serialVersionUID = -3270893239281340723L;

	private String name;
	
	private Long id;
	
	private Integer age;
	
	private Integer sex;

	public void Clear(){
		this.name = null;
		this.id = null;
		this.age = null;
		this.sex = null;
	}
	
	@Override
	public String toString() {
		return this.getClass().getSimpleName() + "name:"
		+ this.name + "age:" + this.age + "sex:" + this.sex;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public Long getId() {
		return id;
	}

	public void setId(Long id) {
		this.id = id;
	}

	public Integer getAge() {
		return age;
	}

	public void setAge(Integer age) {
		this.age = age;
	}

	public Integer getSex() {
		return sex;
	}

	public void setSex(Integer sex) {
		this.sex = sex;
	}
	
}

package service;

import java.util.List;
import java.util.Map;

import domain.People;

public interface PeopleService {

	List batchAddPeople(List peoples);
	
	List batchDelPeople(List peoples);
	
	List batchUpdPeople(List peoples);
	
	Map> batchQuyPeople(List peoples);
	
	void testTransaction();
}

package serviceimpl;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import dao.PeopleDao;
import domain.People;
import service.PeopleService;

@Service(value = "peopleService")
public class PeopleServiceImpl implements PeopleService{

	@Autowired
	private PeopleDao peopleDao;
	
	public PeopleDao getPeopleDao() {
		return peopleDao;
	}

	public void setPeopleDao(PeopleDao peopleDao) {
		this.peopleDao = peopleDao;
	}

	@Override
	public List batchAddPeople(List peoples) {
		for(People people : peoples){
			people = peopleDao.addPeople(people);
		}
		return peoples;
	}

	@Override
	public List batchDelPeople(List peoples) {
		for(People people : peoples){
			people = peopleDao.delPeople(people);
		}
		return peoples;
	}

	@Override
	public List batchUpdPeople(List peoples) {
		for(People people : peoples){
			people = peopleDao.updatePeople(people);
		}
		return peoples;
	}

	@Override
	public Map> batchQuyPeople(
			List peoples) {
		Map> result = new HashMap<>(peoples.size());
		for(People people : peoples){
			List oneresult = peopleDao.queryPeople(people);
			result.put(people, oneresult);
		}
		return result;
	}
	
	@Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, readOnly = false)
	@Override
	public void testTransaction(){
		peopleDao.testTransaction();
	}
	
}

3.2.3xml文件

aop.xml



	
	
	
	
	

bean.xml



	
	

dataBase.xml



	
	
		
		
			oracle.jdbc.driver.OracleDriver
		
		
		
			jdbc:oracle:thin:@127.0.0.1:1521:oracle
		
		
			study
		
		
			study
		
	
	
	
		
		
		
	
	
	

transaction.xml



	
	
		
	
	
	

3.2.4运行结果

Peoplename:aPeopleage:23sex:0
Peoplename:bPeopleage:32sex:1
Service Info    2019-33-28 19:33:44,44  [batchAddPeople]    before
Transaction Info    2019-33-28 19:33:44,44  [batchAddPeople]    before
Dao     Info    2019-33-28 19:33:44,44  [addPeople]    before
Dao     Info    2019-33-28 19:33:44,44  [addPeople]    afterReturn
Dao     Info    2019-33-28 19:33:44,44  [addPeople]    before
Dao     Info    2019-33-28 19:33:44,44  [addPeople]    afterReturn
Service Info    2019-33-28 19:33:44,44  [batchAddPeople]    afterReturn
Transaction Info    2019-33-28 19:33:44,44  [batchAddPeople]    afterReturn
Peoplename:aPeopleage:23sex:0
Peoplename:bPeopleage:32sex:1
Peoplename:aPeopleupdateage:23sex:0
Peoplename:bPeopleupdateage:32sex:1
Service Info    2019-33-28 19:33:44,44  [batchUpdPeople]    before
Transaction Info    2019-33-28 19:33:44,44  [batchUpdPeople]    before
Dao     Info    2019-33-28 19:33:44,44  [updatePeople]    before
Dao     Info    2019-33-28 19:33:44,44  [updatePeople]    afterReturn
Dao     Info    2019-33-28 19:33:44,44  [updatePeople]    before
Dao     Info    2019-33-28 19:33:44,44  [updatePeople]    afterReturn
Service Info    2019-33-28 19:33:44,44  [batchUpdPeople]    afterReturn
Transaction Info    2019-33-28 19:33:44,44  [batchUpdPeople]    afterReturn
Service Info    2019-33-28 19:33:44,44  [batchQuyPeople]    before
Transaction Info    2019-33-28 19:33:44,44  [batchQuyPeople]    before
Dao     Info    2019-33-28 19:33:44,44  [queryPeople]    before
Dao     Info    2019-33-28 19:33:44,44  [queryPeople]    afterReturn
Dao     Info    2019-33-28 19:33:44,44  [queryPeople]    before
Dao     Info    2019-33-28 19:33:44,44  [queryPeople]    afterReturn
Service Info    2019-33-28 19:33:44,44  [batchQuyPeople]    afterReturn
Transaction Info    2019-33-28 19:33:44,44  [batchQuyPeople]    afterReturn
query:Peoplename:aPeopleupdateage:23sex:0
result:Peoplename:aPeopleupdateage:23sex:0
query:Peoplename:bPeopleupdateage:32sex:1
result:Peoplename:bPeopleupdateage:32sex:1
Peoplename:nullage:nullsex:null
Service Info    2019-33-28 19:33:44,44  [batchDelPeople]    before
Transaction Info    2019-33-28 19:33:44,44  [batchDelPeople]    before
Dao     Info    2019-33-28 19:33:44,44  [delPeople]    before
Dao     Info    2019-33-28 19:33:44,44  [delPeople]    afterReturn
Service Info    2019-33-28 19:33:44,44  [batchDelPeople]    afterReturn
Transaction Info    2019-33-28 19:33:44,44  [batchDelPeople]    afterReturn
Peoplename:nullage:nullsex:null
Service Info    2019-33-28 19:33:45,45  [testTransaction]    before
Transaction Info    2019-33-28 19:33:45,45  [testTransaction]    before
Dao     Info    2019-33-28 19:33:45,45  [testTransaction]    before
Exception in thread "main" java.lang.ArithmeticException: / by zero
	at daoimpl.PeopleDaoImpl.testTransaction(PeopleDaoImpl.java:102)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:343)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:198)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
	at org.springframework.aop.framework.adapter.MethodBeforeAdviceInterceptor.invoke(MethodBeforeAdviceInterceptor.java:56)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
	at org.springframework.aop.framework.adapter.AfterReturningAdviceInterceptor.invoke(AfterReturningAdviceInterceptor.java:55)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
	at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:93)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
	at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212)
	at com.sun.proxy.$Proxy19.testTransaction(Unknown Source)
	at serviceimpl.PeopleServiceImpl.testTransaction(PeopleServiceImpl.java:69)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:343)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:198)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
	at org.springframework.aop.framework.adapter.MethodBeforeAdviceInterceptor.invoke(MethodBeforeAdviceInterceptor.java:56)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
	at org.springframework.aop.framework.adapter.MethodBeforeAdviceInterceptor.invoke(MethodBeforeAdviceInterceptor.java:56)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
	at org.springframework.aop.framework.adapter.AfterReturningAdviceInterceptor.invoke(AfterReturningAdviceInterceptor.java:55)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
	at org.springframework.aop.framework.adapter.AfterReturningAdviceInterceptor.invoke(AfterReturningAdviceInterceptor.java:55)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
	at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:294)
	at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:98)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
	at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:93)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
	at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212)
	at com.sun.proxy.$Proxy21.testTransaction(Unknown Source)
	at client.Main.main(Main.java:104)

4.总结

使用注解虽然很方便,但是,在每一个方法上面都配置
@Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, readOnly = false)
这么多,也是一个工作量非常大的任务。

所以,使用xml与注解相结合的方式,能够大大的减轻工作量。
因为每一个注解配置的内容都相同,所以,在xml中配置:
transaction.xml



	
	
		
	
	
	
	
	
		
						
		
	

然后在Java代码中只需要在方法上面增加:
@Transactional
注解即可。
运行结果与原结果相同。

你可能感兴趣的:(java,spring,spring)