Day_06 Spring
文章目录
- 01-切入点表达式(掌握)
- 02-切入点表达式抽取(掌握)
- 03-通知类别(掌握)
- 04-通知获取切入点输入参数(掌握)
- 05-通知获取切入点返回值(掌握)
- 06-通知获取切入点异常对象(掌握)
- 07-AOP注解开发(掌握)
- 08-AOP注解获取切入点输入参数(掌握)
- 09-AOP注解获取切入点返回值(掌握)
- 10-AOP注解获取切入点异常(掌握)
- 11-AOP对根据类型获取bean的影响场景一(掌握)
- 12-AOP对根据类型获取bean的影响场景二(掌握)
- 13-JdbcTemplate模板类使用(了解)
- 14-Spring事务概念(掌握)
- 15-PlatformTransactionManager接口概述(掌握)
- 16-TransactionDefinition接口概述(掌握)
- 17-TransactionStatus接口概述(掌握)
- 18-Spring事务环境搭建(掌握)
- 19-Spring编程式事务基础版(掌握)
- 20-Spring编程式事务优化版(掌握)
- 21-Spring编程式事务终极版(掌握)
- 22-Spring声明式事务概述(掌握)
- 23-xml声明式事务(掌握)
- 24-xml声明式事务配置(掌握)
- 25-注解声明式事务(掌握)
- 26-事务的readOnly属性(掌握)
- 27-事务的timeout属性(掌握)
- 28-事务的回滚和不回滚的异常(掌握)
- 29-事务的隔离级别(掌握)
01-切入点表达式(掌握)
①标准写法
execution(public void com.panghu.service.impl.UserServiceImpl.addUser(com.panghu.pojo.User))
②省略权限修饰符
execution(void com.panghu.service.impl.UserServiceImpl.addUser(com.panghu.pojo.User))
③返回值使用通配符
execution(* com.panghu.service.impl.UserServiceImpl.addUser(com.panghu.pojo.User))
④包名使用通配符
execution(* *.*.*.*.UserServiceImpl.addUser(com.panghu.pojo.User))
⑤表示任意包及其子包的通配符
execution(* *..UserServiceImpl.addUser(com.panghu.pojo.User))
⑥类名使用通配符
execution(* *..*ServiceImpl.addUser(com.panghu.pojo.User))
⑦方法名使用通配符
execution(* *..*ServiceImpl.*(com.panghu.pojo.User))
⑧参数使用通配符
execution(* *..*ServiceImpl.*(..))
⑨全通配符写法(不推荐)
execution(* *..*.*(..))
注意事项
- 通知往往作用于service层
02-切入点表达式抽取(掌握)
代码实现1
<aop:config><aop:aspect ref="myAdvice1"><aop:beforemethod="checkPermission"pointcut="execution(* *..*.*(..))"></aop:before></aop:aspect> </aop:config>
代码实现2
<aop:config><aop:aspect ref="myAdvice1"><aop:pointcut id="p1" expression="execution(* *..*ServiceImpl.*(..))"/><aop:beforemethod="checkPermission"pointcut-ref="p1"></aop:before><aop:aftermethod="printLog"pointcut-ref="p1"></aop:after></aop:aspect> </aop:config>
代码实现3
<aop:config><aop:pointcut id="p1" expression="execution(* *..*ServiceImpl.*(..))"/><aop:aspect ref="myAdvice1"><aop:beforemethod="checkPermission"pointcut-ref="p1"></aop:before></aop:aspect><aop:aspect ref="myAdvice1"><aop:aftermethod="printLog"pointcut-ref="p1"></aop:after></aop:aspect> </aop:config>
03-通知类别(掌握)
概述
通知类别 说明 before 前置通知,在切入点之前执行 after-returning 正常后置通知,在切入点之后执行,切入点没有异常才执行 after-throwing 异常后置通知,在切入点之后执行,切入点有异常才执行 after 后置通知,在切入点之后执行,切入点不管有没有异常都执行 around 环绕通知,在切入点前后都执行 代码实现
@Component public class MyAdvice2 {public void before(){System.out.println("MyAdvice2 before");}public void afterReturning(){System.out.println("MyAdvice2 afterReturning");}public void afterThrowing(){System.out.println("MyAdvice2 afterThrowing");}public void after(){System.out.println("MyAdvice2 after");}public void around(ProceedingJoinPoint pjp){System.out.println("MyAdvice2 around 之前");try {//执行切入点pjp.proceed();} catch (Throwable throwable) {throwable.printStackTrace();throw new RuntimeException(throwable);}System.out.println("MyAdvice2 around 之后");}}
<aop:config><aop:aspect ref="myAdvice2"><aop:pointcut id="p1" expression="execution(* *..*ServiceImpl.*(..))"/><aop:before method="before" pointcut-ref="p1"></aop:before><aop:after-returning method="afterReturning" pointcut-ref="p1"></aop:after-returning><aop:after-throwing method="afterThrowing" pointcut-ref="p1"></aop:after-throwing><aop:after method="after" pointcut-ref="p1"></aop:after><aop:around method="around" pointcut-ref="p1"></aop:around></aop:aspect></aop:config>
04-通知获取切入点输入参数(掌握)
分类
- ①环绕通知获取切入点输入参数
- ②非环绕通知获取切入点输入参数
代码实现
@Component public class MyAdvice3 {/*** ①环绕通知获取切入点输入参数* @param pjp*/public void around(ProceedingJoinPoint pjp){Object[] args = pjp.getArgs();System.out.println("MyAdvice3 around " + Arrays.toString(args));try {pjp.proceed();} catch (Throwable throwable) {throwable.printStackTrace();}}/*** ②非环绕通知获取切入点输入参数* @param jp*/public void before(JoinPoint jp){Object[] args = jp.getArgs();System.out.println("MyAdvice3 before " + Arrays.toString(args));}}
05-通知获取切入点返回值(掌握)
概述
- before : 无法获取
- after-returning : 可以获取
- after-throwing : 无法获取
- after : 无法获取
- around : 可以获取
代码实现
<aop:config><aop:aspect ref="myAdvice4"><aop:pointcut id="p1" expression="execution(* *..*ServiceImpl.*(..))"/><aop:around method="around" pointcut-ref="p1"></aop:around><aop:after-returning method="afterReturning" pointcut-ref="p1" returning="result"></aop:after-returning></aop:aspect></aop:config>
@Component public class MyAdvice4 {public Object around(ProceedingJoinPoint pjp){try {Object result = pjp.proceed();System.out.println("MyAdvice4 around result " + result);return result;} catch (Throwable throwable) {throwable.printStackTrace();}return null;}public void afterReturning(Object result){System.out.println("MyAdvice4 afterReturning result " + result);}}
06-通知获取切入点异常对象(掌握)
概述
- before : 无法获取
- after-returning : 无法获取
- after-throwing : 可以获取
- after : 无法获取
- around : 可以获取
代码实现
<aop:config><aop:aspect ref="myAdvice5"><aop:pointcut id="p1" expression="execution(* *..*ServiceImpl.*(..))"/><aop:around method="around" pointcut-ref="p1" ></aop:around><aop:after-throwing method="afterThrowing" pointcut-ref="p1" throwing="e"></aop:after-throwing></aop:aspect></aop:config>
@Component public class MyAdvice5 {public void afterThrowing(Exception e){System.out.println("MyAdvice5 afterThrowing exception " + e);}public void around(ProceedingJoinPoint pjp){try {pjp.proceed();} catch (Throwable throwable) {throwable.printStackTrace();System.out.println("MyAdvice5 around exception " + throwable);throw new RuntimeException(throwable);}}}
07-AOP注解开发(掌握)
开发步骤
- ①编写spring.xml
- 开启AOP注解支持
- ②制作目标对象类
- ③制作通知类
- 使用@Aspect,@Before,@After,@AfterReturning,@AfterThrowing,@Around
- ④代码测试
- ①编写spring.xml
①编写spring.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans"xmlns:context="http://www.springframework.org/schema/context"xmlns:aop="http://www.springframework.org/schema/aop"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsdhttp://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><context:component-scan base-package="com.atguigu"></context:component-scan><!--07-AOP注解开发--><!--开启AOP注解支持--><aop:aspectj-autoproxy></aop:aspectj-autoproxy></beans>
②制作目标对象类
③制作通知类
@Aspect @Component public class MyAdvice6 {@Before("execution(* *..*Service.*(..))")public void before(){System.out.println("MyAdvice6 before");}@AfterReturning("execution(* *..*Service.*(..))")public void afterReturning(){System.out.println("MyAdvice6 afterReturning");}@AfterThrowing("execution(* *..*Service.*(..))")public void afterThrowing(){System.out.println("MyAdvice6 afterThrowing");}@After("execution(* *..*Service.*(..))")public void after(){System.out.println("MyAdvice6 after");}@Around("execution(* *..*Service.*(..))")public void around(ProceedingJoinPoint pjp){System.out.println("MyAdvice6 around 之前");try {//执行切入点pjp.proceed();} catch (Throwable throwable) {throwable.printStackTrace();throw new RuntimeException(throwable);}System.out.println("MyAdvice6 around 之后");}}
08-AOP注解获取切入点输入参数(掌握)
概述
- ①环绕通知获取切入点输入参数
- ②非环绕通知获取切入点输入参数
代码实现
@Aspect @Component public class MyAdvice7 {/*** ①环绕通知获取切入点输入参数* @param pjp*/@Around("execution(* *..*Service.*(..))")public void around(ProceedingJoinPoint pjp){Object[] args = pjp.getArgs();System.out.println("MyAdvice3 around " + Arrays.toString(args));try {pjp.proceed();} catch (Throwable throwable) {throwable.printStackTrace();}}/*** ②非环绕通知获取切入点输入参数* @param jp*/@Before("execution(* *..*Service.*(..))")public void before(JoinPoint jp){Object[] args = jp.getArgs();System.out.println("MyAdvice3 before " + Arrays.toString(args));}}
09-AOP注解获取切入点返回值(掌握)
概述
- after-returning : 可以获取
- around : 可以获取
代码实现
@Aspect @Component public class MyAdvice8 {@Around("execution(* *..*Service.*(..))")public Object around(ProceedingJoinPoint pjp){try {Object result = pjp.proceed();//执行切入点System.out.println("MyAdvice4 around result " + result);return result;} catch (Throwable throwable) {throwable.printStackTrace();}return null;}@AfterReturning(pointcut = "execution(* *..*Service.*(..))" ,returning = "result")public void afterReturning(Object result){System.out.println("MyAdvice4 afterReturning result " + result);}}
10-AOP注解获取切入点异常(掌握)
概述
- ①after-throwing : 可以获取
- ②around : 可以获取
代码实现
@Aspect @Component public class MyAdvice9 {@AfterThrowing(pointcut = "execution(* *..*Service.*(..))" ,throwing = "e")public void afterThrowing(Exception e){System.out.println("MyAdvice5 afterThrowing exception " + e);}@Around("execution(* *..*Service.*(..))")public void around(ProceedingJoinPoint pjp){try {pjp.proceed();} catch (Throwable throwable) {throwable.printStackTrace();System.out.println("MyAdvice5 around exception " + throwable);throw new RuntimeException(throwable);}}}
11-AOP对根据类型获取bean的影响场景一(掌握)
- 需求
- 一个接口,该接口有一个实现子类
- 定义一个通知类,通知类作用于实现子类
- ①根据接口类型获取bean对象
- ②根据实现子类类型获取bean对象
- ①根据接口类型获取bean对象
- 可以正常获取
- ②根据实现子类类型获取bean对象
- 无法获取
- 原因分析
- 目标对象类如果运用了AOP通知,那么放入到Spring容器中的是代理类对象,而不是目标对象类
- 代理类对象和目标对象类实现了同一个接口.
- 底层使用JDKProxy
12-AOP对根据类型获取bean的影响场景二(掌握)
- 需求
- 声明一个类,创建一个通知类,对上面的类应用通知
- ①根据类的类型来获取bean对象
- ①根据类的类型来获取bean对象
- 可以正常获取
- 原因分析
- 目标对象类如果运用了AOP通知,那么放入到Spring容器中的是代理类对象,而不是目标对象类
- 代理类对象继承于目标对象类
- 底层使用CGLIB
13-JdbcTemplate模板类使用(了解)
概述
- Spring框架内置的操作数据库的技术.
开发步骤
- ①引入依赖
- spring-jdbc,druid,mysql
- ②编写spring.xml
- ③定义dao及其实现子类
- ④代码测试
- ①引入依赖
①引入依赖
<dependencies><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.13.2</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.22</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-core</artifactId><version>5.3.16</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-beans</artifactId><version>5.3.16</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.3.16</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-expression</artifactId><version>5.3.16</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-test</artifactId><version>5.3.16</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-jcl</artifactId><version>5.3.16</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-aop</artifactId><version>5.3.16</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-aspects</artifactId><version>5.3.16</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-jdbc</artifactId><version>5.3.16</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.2.8</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.49</version></dependency></dependencies>
②编写spring.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans"xmlns:context="http://www.springframework.org/schema/context"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><context:component-scan base-package="com.panghu"></context:component-scan><bean class="org.springframework.jdbc.core.JdbcTemplate"><constructor-arg name="dataSource" ref="dataSource"></constructor-arg></bean><context:property-placeholder location="jdbc.properties"></context:property-placeholder><bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"><property name="driverClassName" value="${driverClassName}"></property><property name="url" value="${jdbcUrl}"></property><property name="username" value="${user}"></property><property name="password" value="${password}"></property></bean></beans>
③定义dao及其实现子类
@Repository public class UserDaoImpl implements UserDao {@Autowiredprivate JdbcTemplate jdbcTemplate;public int addUser(User inputUser) throws Exception {return jdbcTemplate.update("insert into t_user values(null,?,?,?,?)",inputUser.getUserName(),inputUser.getUserPwd(),inputUser.getMoney(),inputUser.getAddress());}public int deleteUserById(Integer userId) throws Exception {return jdbcTemplate.update("delete from t_user where userId = ?",userId);}public int updateUser(User inputUser) throws Exception {return jdbcTemplate.update("update t_user set userName=?,userPwd=?,money=?,address=? where userId=?",inputUser.getUserName(),inputUser.getUserPwd(),inputUser.getMoney(),inputUser.getAddress(),inputUser.getUserId());}public User selectUserById(Integer userId) throws Exception {return jdbcTemplate.queryForObject("select * from t_user where userId= ?",new RowMapper<User>() {public User mapRow(ResultSet rs, int rowNum) throws SQLException {User user = new User();user.setUserId(rs.getInt("userId"));user.setUserName(rs.getString("userName"));user.setUserPwd(rs.getString("userPwd"));user.setMoney(rs.getDouble("money"));user.setAddress(rs.getString("address"));return user;}},userId);}public List<User> selectUserList() throws Exception {return jdbcTemplate.query("select * from t_user",new BeanPropertyRowMapper<User>(User.class));} }
④代码测试
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = "classpath:spring.xml") public class UserDaoTest {@Autowiredprivate UserDao userDao;@Testpublic void addUser() throws Exception {userDao.addUser(new User(null,"xyz","xyz",10000.0,"武汉市"));}@Testpublic void deleteUserById() {}@Testpublic void updateUser() {}@Testpublic void selectUserById() throws Exception {System.out.println("user = " + userDao.selectUserById(19));}@Testpublic void selectUserList() throws Exception {List<User> userList = userDao.selectUserList();System.out.println("userList = " + userList);} }
14-Spring事务概念(掌握)
- 概述
- Spring进行事务管理,有两种方式:编程式事务,声明式事务
- 分类
- 编程式事务
- 声明式事务
- XML声明
- 注解声明
- 核心对象
- PlatformTransactionManager : 事务管理类
- TransactionDefinition : 事务配置类
- TransactionStatus : 事务状态类
15-PlatformTransactionManager接口概述(掌握)
- 概述
- 此接口定义了spring 的事务管理器,提供常用的操作事务的方法
- 常用方法
- getTransaction : 开启事务
- commit : 提交事务
- rollback : 回滚事务
- 继承结构
- DataSourceTransactionManager : 适用于spring-jdbc , mybatis
- HibernateTransactionManager : 适用于hibernate
- JpaTransactionManager : 适用于jpa
16-TransactionDefinition接口概述(掌握)
- 概述
- 定义事务的属性(隔离级别,传播行为,超时,只读性,不回滚的异常和回滚的异常…)
- 常用方法
- getPropagationBehavior/setPropagationBehavior : 获取/设置传播行为
- getIsolationLevel/setIsolationLevel : 获取/设置隔离级别
- getTimeout/setTimeout : 获取/设置超时
- isReadOnly/setReadOnly : 获取/设置只读性
- 继承结构
- DefaultTransactionDefinition
17-TransactionStatus接口概述(掌握)
- 概述
- 此接口定义了事务在执行过程中某个时间点上的状态信息及对应的状态操作
- 继承结构
- DefaultTransactionStatus
18-Spring事务环境搭建(掌握)
需求
- 完成转账业务
代码实现
@Service public class UserServiceImpl implements UserService {@Autowiredprivate UserDao userDao;public void transfer(String outName, String inName, Double money) throws Exception {//出账userDao.outMoney(outName, money);System.out.println(1 / 0);//入账userDao.inMoney(inName, money);}}
@Repository public class UserDaoImpl implements UserDao {@Autowiredprivate JdbcTemplate jdbcTemplate;public void outMoney(String outName, Double money) throws Exception {jdbcTemplate.update("update t_user set money = money - ? where userName = ?",money,outName);}public void inMoney(String inName, Double money) throws Exception {jdbcTemplate.update("update t_user set money = money + ? where userName = ?",money,inName);} }
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = "classpath:spring.xml") public class UserServiceTest {@Autowiredprivate UserService userService;@Testpublic void transfer() throws Exception {userService.transfer("张三", "李四", 1000.0);} }
19-Spring编程式事务基础版(掌握)
概述
- 使用DataSourceTransactionManager进行事务管理
代码实现
<!--事务管理器--> <bean class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="dataSource"></property> </bean><!--事务属性1--> <bean id="definition1" class="org.springframework.transaction.support.DefaultTransactionDefinition"><property name="isolationLevel" value="4"></property> </bean><!--事务属性2--> <bean id="definition2" class="org.springframework.transaction.support.DefaultTransactionDefinition"><property name="isolationLevel" value="2"></property> </bean>
@Service public class UserServiceImpl implements UserService {@Autowiredprivate UserDao userDao;@Autowiredprivate DataSourceTransactionManager transactionManager;@Autowired@Qualifier("definition1")private TransactionDefinition definition;public void transfer(String outName, String inName, Double money) throws Exception {TransactionStatus status = null;try {//开启事务status = transactionManager.getTransaction(definition);//出账userDao.outMoney(outName, money);System.out.println(1 / 0);//入账userDao.inMoney(inName, money);//提交事务transactionManager.commit(status);} catch (Exception e) {e.printStackTrace();//回滚事务transactionManager.rollback(status);}}}
存在问题
- 可以将事务管理的代码抽取成独立的工具类进行复用.
20-Spring编程式事务优化版(掌握)
代码实现
@Component public class MyTransactionManager {@Autowiredprivate DataSourceTransactionManager transactionManager;@Autowired@Qualifier("definition1")private TransactionDefinition definition;/*** 开启事务* @return*/public TransactionStatus startTransaction(){return transactionManager.getTransaction(definition);}/*** 提交事务* @param status*/public void commit(TransactionStatus status){transactionManager.commit(status);}/*** 回滚事务* @param status*/public void rollback(TransactionStatus status){transactionManager.rollback(status);}}
@Service public class UserServiceImpl implements UserService {@Autowiredprivate UserDao userDao;@Autowiredprivate MyTransactionManager transactionManager;public void transfer(String outName, String inName, Double money) throws Exception {TransactionStatus status = null;try {//开启事务status = transactionManager.startTransaction();//出账userDao.outMoney(outName, money);System.out.println(1 / 0);//入账userDao.inMoney(inName, money);//提交事务transactionManager.commit(status);} catch (Exception e) {e.printStackTrace();//回滚事务transactionManager.rollback(status);}}}
存在问题
- 如果业务层中的所有功能都需要进行事务管理,那么就会重复大量去写事务管理代码,可以将事务管理代码制作成通知类.
21-Spring编程式事务终极版(掌握)
代码实现1
@Component public class TransactionAdvice {@Autowiredprivate MyTransactionManager transactionManager;public void txAround(ProceedingJoinPoint pjp){//开启事务TransactionStatus status = transactionManager.startTransaction();try {pjp.proceed();//执行切入点//提交事务transactionManager.commit(status);} catch (Throwable throwable) {throwable.printStackTrace();//回滚事务transactionManager.rollback(status);}}}
<aop:config><aop:aspect ref="transactionAdvice"><aop:around method="txAround" pointcut="execution(* *..*Service.*(..))"></aop:around></aop:aspect></aop:config>
代码实现2
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
@Aspect @Component public class TransactionAdvice {@Autowiredprivate MyTransactionManager transactionManager;@Around("execution(* *..*Service.*(..))")public void txAround(ProceedingJoinPoint pjp){//开启事务TransactionStatus status = transactionManager.startTransaction();try {pjp.proceed();//执行切入点//提交事务transactionManager.commit(status);} catch (Throwable throwable) {throwable.printStackTrace();//回滚事务transactionManager.rollback(status);}}}
22-Spring声明式事务概述(掌握)
- 概述
- 将编程式事务中的通用代码抽取出来,制作成独立的around通知使用AOP工作原理,将事务管理的 代码动态织入到原始方法中。由于该功能使用量较大,Spring已经将该通知制作完毕。
- 开发人员只需要通过xml配置或注解配置的方式进行使用即可
- 分类
- xml声明式事务
- 注解声明式事务
23-xml声明式事务(掌握)
开发步骤
- ①配置内置事务通知类
- 配置事务策略
- ②将内置事务通知作用到对应的切入点
- ①配置内置事务通知类
代码实现
<tx:advice id="txAdvice" transaction-manager="transactionManager"><tx:attributes><!--transfer方法的事务属性--><tx:method name="transfer" isolation="REPEATABLE_READ"/><!--addUser方法的事务属性--><tx:method name="addUser" isolation="REPEATABLE_READ"/></tx:attributes> </tx:advice><aop:config><aop:advisor advice-ref="txAdvice" pointcut="execution(* *..*Service.*(..))"></aop:advisor> </aop:config>
24-xml声明式事务配置(掌握)
代码实现1
<!--事务通知--> <tx:advice id="txAdvice" transaction-manager="transactionManager"><tx:attributes><!--transfer方法的事务属性--><tx:method name="transfer" isolation="REPEATABLE_READ" read-only="false"/><!--addUser方法的事务属性--><tx:method name="addUser" isolation="REPEATABLE_READ" read-only="false"/><tx:method name="deleteUserById" isolation="REPEATABLE_READ" read-only="false"></tx:method><tx:method name="updateUser" isolation="REPEATABLE_READ" read-only="false"></tx:method><tx:method name="selectUserById" isolation="REPEATABLE_READ" read-only="true"></tx:method><tx:method name="selectUserList" isolation="REPEATABLE_READ" read-only="true"></tx:method></tx:attributes> </tx:advice><aop:config><aop:advisor advice-ref="txAdvice" pointcut="execution(* *..*Service.*(..))"></aop:advisor> </aop:config>
代码实现2
<!--事务通知--> <tx:advice id="txAdvice" transaction-manager="transactionManager"><tx:attributes><!--transfer方法的事务属性--><tx:method name="transfer" isolation="REPEATABLE_READ" read-only="false"/><!--addUser方法的事务属性--><tx:method name="add*" isolation="REPEATABLE_READ" read-only="false"/><tx:method name="delete*" isolation="REPEATABLE_READ" read-only="false"></tx:method><tx:method name="update*" isolation="REPEATABLE_READ" read-only="false"></tx:method><tx:method name="select*" isolation="REPEATABLE_READ" read-only="true"></tx:method></tx:attributes> </tx:advice><aop:config><aop:advisor advice-ref="txAdvice" pointcut="execution(* *..*Service.*(..))"></aop:advisor> </aop:config>
25-注解声明式事务(掌握)
开发步骤
- ①开启事务注解支持
- ②在service上加上@Transactional
代码实现
<!--事务管理器--> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="dataSource"></property> </bean><!--开启事务注解支持--> <tx:annotation-driven transaction-manager="transactionManager"></tx:annotation-driven>
@Transactional(readOnly = true) @Service public class UserServiceImpl implements UserService {@Autowiredprivate UserDao userDao;@Transactional(readOnly = false)public void transfer(String outName, String inName, Double money) throws Exception {//出账userDao.outMoney(outName, money);System.out.println(1 / 0);//入账userDao.inMoney(inName, money);}@Transactional(readOnly = false)public int addUser(User inputUser) throws Exception {int addUser = userDao.addUser(inputUser);System.out.println(1 / 0);return addUser;}@Transactional(readOnly = false)public int deleteUserById(Integer userId) throws Exception {return userDao.deleteUserById(userId);}@Transactional(readOnly = false)public int updateUser(User inputUser) throws Exception {return userDao.updateUser(inputUser);}public User selectUserById(Integer userId) throws Exception {return userDao.selectUserById(userId);}public List<User> selectUserList() throws Exception {return userDao.selectUserList();}}
26-事务的readOnly属性(掌握)
- 概述
- 对一个查询操作来说,如果我们把它设置成只读,就能够明确告诉数据库,这个操作不涉及写操作。 这样数据库就能够针对查询操作来进行优化。
- 代码实现
- 注意事项
- readOnly = true 只能设置在读操作上,否则会报错!Connection is read-only. Queries leading to data modification are not allowed;
27-事务的timeout属性(掌握)
概述
- 超时回滚,释放资源。
代码实现
@Transactional(readOnly = false ,timeout = 3) public int addUser(User inputUser) throws Exception {Thread.sleep(5000);int addUser = userDao.addUser(inputUser);//操作数据库return addUser;}
注意事项
- 超时操作需要在操作数据库之前.
28-事务的回滚和不回滚的异常(掌握)
概述
- 默认情况,遇到运行时异常回滚,遇到编译期异常不回滚。
- rollbackFor设置哪些异常需要回滚
- noRollbackFor设置哪些异常不需要回滚
代码实现
@Transactional(readOnly = false, rollbackFor = Exception.class ,noRollbackFor = ArithmeticException.class) public int addUser(User inputUser) throws Exception {int addUser = userDao.addUser(inputUser);//操作数据库//FileNotFoundException : 编译期异常不会回滚//new FileInputStream("aaa.txt");//ArithmeticException : 运行时异常才会回滚System.out.println(1 / 0);return addUser;}
29-事务的隔离级别(掌握)
隔离级别
- READ UNCOMMITTED : 读未提交
- 脏读 ,不可重复读, 幻读
- READ COMMITTED : 读已提交
- 不可重复读, 幻读
- REPEATABLE READ : 可重复读
- 幻读
- SERIALIZABLE : 串行化
- 效率低
- READ UNCOMMITTED : 读未提交
脏读
- 一个事务可以读取到另一个事务中未提交的数据
不可重复读
- 一个事务多次读取另一个事务中的同一个数据,前后不一致
幻读
- 一个事务查询一条记录显示没有,该事务添加这条记录又显示有.
代码实现
@Transactional(readOnly = false, isolation = Isolation.REPEATABLE_READ) public int addUser(User inputUser) throws Exception {int addUser = userDao.addUser(inputUser);//操作数据库return addUser;}@Transactional(readOnly = true,isolation = Isolation.REPEATABLE_READ) public List<User> selectUserList() throws Exception {return userDao.selectUserList(); }
Day_06 Spring相关推荐
- spring boot项目 中止运行 最常用的几种方法
spring boot项目 中止运行 最常用的几种方法: 1. 调用接口,停止应用上下文 @RestController public class ShutdownController impleme ...
- html+spring boot简单的ajax数据传输实现
本篇讲解在前后端不分离情况下的html+spring boot的项目数据传输实现 首先,后台我写了三个接口 package com.demo.ajax.controller;import com.de ...
- Spring Boot整合Spring Data JPA操作数据
一. Sping Data JPA 简介 Spring Data JPA 是 Spring 基于 ORM 框架.JPA 规范的基础上封装的一套 JPA 应用框架,底层使用了 Hibernate 的 J ...
- Spring AOP + Redis解决重复提交的问题
Spring AOP + Redis解决重复提交的问题 用户在点击操作的时候,可能会连续点击多次,虽然前端可以通过设置按钮的disable的属性来控制按钮不可连续点击,但是如果别人拿到请求进行模拟,依 ...
- Spring cloud 微服务docker容器化最佳实践
Spring cloud 是当下最炙手可热的微服务套件,我们将介绍如何整合Docker容器达到高效快捷的构建发布 采用了dockerfile-maven-plugin插件发布镜像到远程docker主机 ...
- ssh(Struts+spring+Hibernate)三大框架整合-简述
ssh(Struts+spring+Hibernate)三大框架配合使用来开发项目,是目前javaee最流行的开发方式,必须掌握: 注意: 为了稳健起见,每加入一个框架,我们就需要测试一下,必须通过才 ...
- Strutsw2与Spring整合流程-简述
1. 新建WEB工程: 2. 导入struts2开发包,和资源配置文件 ① globalMessages.properties ② struts.properties 3. ...
- spring Bean自动装配
spring Bean自动装配 自动装配是使用spring满足bean依赖的一种方式. spring会在应用上下文中为某个bean寻找其依赖的bean. spring自动装配需要从两个角度来实现,或者 ...
- spring IOC创建对象方式
spring IOC创建对象方式 通过无参构造来创建 验证方法: 创建实体类: public class User {private String name;public User() {System ...
最新文章
- vue渲染大量数据如何优化_Vue3 Compiler 优化细节,如何手写高性能渲染函数
- [转].Net实现本地化简易教程
- html5家谱资源网,免费家谱系统(ASP,Access,CSS,html5)
- BZOJ1861: [Zjoi2006]Book 书架
- java多态的简单例子_要JAVA的简单例子,继承\多态的,详细讲解运行的每一步
- 在silverlight中,创建webservice的client报错
- .net 连接ORACLE 数据库字符串
- (DT系列四)驱动加载中, 如何取得device tree中的属性
- 异常——Python
- C++中char[]转string
- 淘宝TOP获取sessionkey
- 窗体程序计算一元二次方程
- ufw命令的基本使用
- WIN10开启Hyper-V虚拟化功能
- 数据结构--逻辑结构
- 为地图marker 设置网络图片
- [荐]硕博经验——科研论文阅读与写作实战技巧
- 大数据开发工程师是做什么的?
- 心理学c语言,心理学史练习题.doc
- 怎样解除锁定计算机,怎样解除电脑屏幕锁定 教你解除电脑屏幕锁定的方法