概念
<!--spring-AOP--> <dependency><groupId>org.springframework</groupId><artifactId>spring-aspects</artifactId><version>5.2.2.RELEASE</version> </dependency>
AOP基础知识
@Before("execution(* com.ffyc.springpro.Dao.AdminDao.*(..))")public void printLog(){System.out.println("打印日志");}
@After("execution(* com.ffyc.springpro.Dao.AdminDao.*(..))")public void printLog(){System.out.println("打印日志");}
连接点:
public void insert(){System.out.println("新增");System.out.println(10/0);}
结果,即使出现异常也会执行
@AfterReturning("execution(* com.ffyc.springpro.Dao.AdminDao.*(..))")public void printLog(){System.out.println("打印日志");}
连接点:
public void insert(){System.out.println("新增");System.out.println(10/0);}
结果,即使出现异常不会执行
@AfterThrowing(value = "execution(* com.ffyc.springpro.Dao.AdminDao.*(..))",throwing = "e")public void exception(Throwable e){System.out.println("系统忙");e.printStackTrace();}
连接点:
public void insert(){System.out.println("新增");System.out.println(10/0);}
连接点:
public void insert(){System.out.println("新增");// System.out.println(10/0);}
@Around("execution(* com.ffyc.springpro.Dao.AdminDao.*(..))")public void around(ProceedingJoinPoint joinPoint){System.out.println("前置通知");try {Object [] objects= joinPoint.getArgs();//获取目标方法的参数joinPoint.proceed();//调用目标业务方法System.out.println(Arrays.toString(objects));System.out.println("返回通知");} catch (Throwable throwable) {throwable.printStackTrace();System.out.println("异常通知");}System.out.println("后置通知");}
连接点
public void insert(String name){System.out.println("新增"+name);// System.out.println(10/0); }
结果
Spring事务管理
事务管理本质上是数据库提供的一种管理机制。数据库在执行一次操作过程中执行的多条语句进行管理,确保多条sql要么都成功执行,要么都不执行,从而保证数据一致性。
数据库事务管理:我们在开发企业应用时,对于业务人员的一个操作实际是对数据读写的多步 操作的结合。由于数据操作在顺序执行的过程中,任何一步操作都有可能发生异 常,异常会导致后续操作无法完成,此时由于业务逻辑并未正确的完成,之前成功操作数据的并不可靠,需要在这种情况下进行回退。 事务的作用就是为了保证用户的每一个操作都是可靠的,事务中的每一步操 作都必须成功执行,只要有发生异常就回退到事务开始未进行操作的状态,这些 操作要么都完成,要么都取消,从而保证数据满足一致性的要求。
spring事务管理是spring框架对事务提交这一功能进行封装,程序员在业务开发中不需要显示的提交事务。
spring事务管理的俩种形式
1、编程式事务管理:需要程序员在代码中自己控制事务提交和回滚
2、声明式事务管理:底层使用了AOP思想,建立在AOP的基础上,可以为方法添加事务功能,它的控制是方法级别的。
基于注解方式实现spring事务管理
先在spring.xml文件中进行配置
<!-- 配置 spring 事务管理器--> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="druidDataSource"></property> </bean><!-- 开启注解事务管理 --> <tx:annotation-driven transaction-manager="transactionManager"/>
@Transactional
public void insert(){System.out.println("新增");jdbcTemplate.update("insert into admin(account,password,gender) values(?,?,?)","张三","111","男");// System.out.println(10/0);jdbcTemplate.update("insert into admin(account,password,gender) values(?,?,?)","张三","111","男");
}
进行测试,如果出现异常,则会自动回滚事务,不出现异常,会向数据库提交。
在实际应用场景中,我们不会将@Transaction添加到dao层(数据访问层),而是添加到service层(业务逻辑层),因为在dao层,方法是执行的是一条sql语句,而service层的方法中会掉用多个dao层的方法,如果添加在了dao层,service层的方法出现了异常,spring还是会将事务提交。
示例:
dao层:
@Transactionalpublic void insert1(){jdbcTemplate.update("insert into admin(account,password,gender) values(?,?,?)","张三1","111","男");}@Transactionalpublic void insert2(){jdbcTemplate.update("insert into admin(account,password,gender) values(?,?,?)","张三2","111","男");}
service层:
public void insertAdmin(){adminDao.insert1();System.out.println(10/0);adminDao.insert2();}
service层的方法出现了异常,原则上是不能将数据提交的数据库的,但是我们 程序还是进行了事务提交。
执行结果:出现了异常
为了解决这一问题,所有我们将@Transaction添加到service层。
@Transactional(rollbackFor = Exception.class)public void insertAdmin(){adminDao.insert1();System.out.println(10/0);adminDao.insert2();}
出现异常则不会提交事务。
声明式事务管理失效场景:
1、@Transactional用在非public方法上,在底层实现上是Java的反射机制,getMethod只能获得是公共方法(public方法),非public方法不能够得到
2、方法中出现异常被catch捕获,那么就会认为没有异常出现
3、方法中出现了编译期异常,还是会提交事务的,可以将@Transactional(rollbackFor = Exception.class)这样所有的异常都会回滚事务
4、数据库引擎不支持事务,mysql中只有innodb引擎支持事务