spring-tx-X.X.X.RELEASE.jar包中:
1.PlatformTransactionManager平台事务管理器
2.TransactionDefinition事务定义或描述对象
3.TransactionStatus事务状态。
1.TransactionStatus getTransaction(@Nullable TransactionDefinition definition) throws TransactionException;
获取事务状态信息。
2.void commit(TransactionStatus status) throws TransactionException;
提交事务。
3.void rollback(TransactionStatus status) throws TransactionException;
回滚事务。
1.String getName();
获取事务对象名称。
2.int getIsolationLevel();
获取事务的隔离级别。
3.int getPropagationBehavior();
获取事务的传播行为。
4.int getTimeout();
获取超时时间。
5.boolean isReadOnly();
获取事务是否只读。
1.void flush();
刷新事务。
2.boolean hasSavepoint();
获取是否存在保存点。
3.boolean isCompleted();
获取事务是否完成。
4.boolean isNewTransaction();
获取是否是新事务。
5.boolean isRollbackOnly();
获取事务是否回滚。
6.void setRollbackOnly();
设置事务回滚。
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();
}
}
aop.xml
bean.xml
dataBase.xml
oracle.jdbc.driver.OracleDriver
jdbc:oracle:thin:@127.0.0.1:1521:oracle
study
study
transaction.xml
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)
使用注解虽然很方便,但是,在每一个方法上面都配置
@Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, readOnly = false)
这么多,也是一个工作量非常大的任务。
所以,使用xml与注解相结合的方式,能够大大的减轻工作量。
因为每一个注解配置的内容都相同,所以,在xml中配置:
transaction.xml
然后在Java代码中只需要在方法上面增加:
@Transactional
注解即可。
运行结果与原结果相同。