Spring事务传播机制
开启事务的传播机制
创建两个方法,这个Service类是被spring容器所扫描的。在该方法上添加@Trancational事务注解。
在insertStudent2()方法上添加上propagation_Requires_new 每次都会创建一个事务、抛出异常
在insertStudent()方法上添加@trancational 相当于配合了propagatin_required 这是默认的。
在insertSudent()方法上调用insertStudent2()方法。
测试之后 就会发现insertStudent2()抛出了异常,但是数据却是插入到的数据库中。
因此 我们探究spring AOP的原理
1.创建一个接口类
2.创建一个实现类
3 创建一个动态代理类
Spring 生成AOP代理类有两种方式 一种是jdk动态代理。(基于接口)一种是cglib动态代理(基于实现类)
4 从测试方法中可以看到我们调用了work方法。在work方法调用了eat方法。但是在console
因此 我们发现我们在上面中调用抛出了异常 但是不会回滚的机制 是有与我们调用的StudentService类来调用。
而不会经过spring AOP代理的类。他是由真实对象类调用。而不是代理对象来调用。
解决方案 1 获取到代理对对象,然后由代理对象调用insertStudent2();
AOPContext.currentProxy();
2 ApplicationContext context = new ApplicatinonContext();获取到代理类对象
附上代码
package hbsi.yfzx.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import hbsi.yfzx.mapper.StudentMapper;
import hbsi.yfzx.pojo.Student;
@Service
public class StudentService {
@Autowired
private StudentMapper studentMapper;
public Integer saveStudent(Student student) {
return studentMapper.insert(student);
}
public Integer deleteStudent(Integer id) {
return studentMapper.deleteByPrimaryKey(id);
}
}
实现类
package com.hbsi.springproxy;
/**
* 目标实现类--真实类
* @author jia
*
*/
public class StudentServiceImpl implements StudentService {
public void work() {
System.out.println("------小明上班---------");
System.out.println("this.getName():"+this.getClass().getName());
System.out.println("this.getClass():"+this.getClass());
eat();
}
public void sleep() {
System.out.println("------小明睡觉---------");
}
public void eat() {
System.out.println("------小明吃饭---------");
}
}
代理接口类
package com.hbsi.springproxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* 接口 代理类
* @author jia
*
*/
public class StudentServiceProxy implements InvocationHandler{
private Object object;//目标类对象
public StudentServiceProxy(Object obj){
System.out.println("obj:"+obj);
object = obj;
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// TODO Auto-generated method stub
if(method.getName().equals("work")||method.getName().equals("eat")){
System.out.println("-------加入事务-----------");
}
return method.invoke(object, args);
}
public static void main(String[] args) {
StudentServiceProxy studentProxy = new StudentServiceProxy(new StudentServiceImpl());
StudentService student = (StudentService)Proxy.newProxyInstance(StudentServiceProxy.class.getClassLoader(),
new Class[]{StudentService.class}
,studentProxy );
student.work();
}
}
测试类
package hbsi.yfzx.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import hbsi.yfzx.mapper.StudentMapper;
import hbsi.yfzx.pojo.Student;
@Service
public class StudentService {
@Autowired
private StudentMapper studentMapper;
public Integer saveStudent(Student student) {
return studentMapper.insert(student);
}
public Integer deleteStudent(Integer id) {
return studentMapper.deleteByPrimaryKey(id);
}
}