spring事务管理方式,aop
达内12 note unit 09 01
1.spring事务管理
2.spring提供了对事务管理支持
spring采用aop机制完成事务控制
可以实现在不修改原有组件代码情况下实现事务控制功能。
spring提供了两种事务管理方式:
a。编程式事务管理(编写java代码)
TransactionTemplate
b.声明式事务管理(编写配置,大家都用这种)
xml版本配置
注解版本配置
--配置DataSourceTransactionManager
--开启事务注解配置<tx:annotation>
--在目标组件方法前添加@Transactional
注解版本例子:
例如UserServiceImpl中的regist注册方法需要事务:
第一步,我们现在applicationContext.xml中配置事务管理组件
<!-- 配置事务管理组件 -->
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dbcp"></property>
</bean>
<!-- 开启事务注解标记@Transactional -->
<!-- 当调用带@Transactional 标记的方法时,将txManager事务管理功能切入到方法-->
<tx:annotation-driven transaction-manager="txManager"/>
第二步,在所有service类上,加上@Transactional注解
package org.alexhe.note.service;
import javax.annotation.Resource;
import org.alexhe.note.dao.IUserDao;
import org.alexhe.note.entity.NoteResult;
import org.alexhe.note.entity.User;
import org.alexhe.note.util.NoteUtil;
import org.springframework.stereotype.Service;
@Service("userService")
@Transactional//这里加入事务注解
public class UserServiceImpl implements IUserService{
@Resource
private IUserDao userDao;//注入
@Override
public NoteResult checkLogin(String name, String pwd) throws Exception {
// TODO Auto-generated method stub
NoteResult result=new NoteResult();
User user=userDao.findByName(name);
if(user==null){
result.setStatus(1);
result.setMsg("用户名不存在");
return result;
}
String md5_pwd=NoteUtil.md5(pwd);
if(!user.getCn_user_password().equals(md5_pwd)){
result.setStatus(2);
result.setMsg("密码不正确");
return result;
}
result.setStatus(0);
result.setMsg("用户名和密码正确");
result.setData(user.getCn_user_id());//返回userid
return result;
}
@Override
public NoteResult regist(String name, String password, String nickname) throws Exception {
NoteResult result=new NoteResult();
//检测用户名是否被占用
User has_user=userDao.findByName(name);
if(has_user!=null){
result.setStatus(1);
result.setMsg("用户名已被占用");
return result;
}
//注册
User user=new User();
user.setCn_user_name(name);
user.setCn_user_desc(nickname);
String md5_pwd=NoteUtil.md5(password);
user.setCn_user_password(md5_pwd);//设置加密的密码
String userId=NoteUtil.createId();
user.setCn_user_id(userId);//设置userid
//调用userDao保存
userDao.save(user);
result.setStatus(0);
result.setMsg("注册成功");
return result;
}
}
xml版本配置例子:(配置比注解版复杂)
第一步,我们现在applicationContext.xml中配置事务管理组件,记得xml里加入aop的头
<!-- 配置事务管理组件 -->
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dbcp"></property>
</bean>
<tx:advice id="txAdvice" transaction-manager="txManager">
<tx:attributes><!-- 哪些方法用事务,就写在里面 -->
<tx:method name="regist"/>
<tx:method name="checkLogin"/>
<tx:method name="add*"/> <!-- 以add开头的所有方法 -->
<!-- <tx:method name="*"/> <!-- 所有方法都加注释 -->
</tx:attributes>
</tx:advice>
<aop:config>
<aop:pointcut id="target" expression="within(org.alexhe.note.service..*)"/> <!-- expression代表哪个组件,作用在哪些组件上,这里代表service包及其下面的所有组件-->
<aop:advisor advice-ref="txAdvice" pointcut-ref="target"/>
</aop:config>
3.Spring对事务管理的控制
a。控制事务可读可写特性
Spring分为可读写事务和只读事务。默认为可读写,一般只涉及查询操作,建议用只读事务
@Transactional(readOnly=true)
b.控制事务是否回滚
Spring遇到runtimeException异常,会回滚。遇到非运行时异常,不会回滚。
@Transactional(readOnly=true,rollbackFor=IOException.class) 这样遇到IOException也会发生回滚。
建议:自定义异常继承自RuntimeException继承
public class MyException extends RuntimeException
c。控制事务传播类型
遇到带有事务控制方法调用另一个事务控制方法时,可以选择合适的传播类型,默认是required类型,后者使用前者事务。
d。控制事务隔离级别
@Transactional(readOnly=true, isolation=Isolation.READ_COMMITED);
由低到高如下:
READ_UNCOMMITED读未提交
READ_COMMITED读已提交
REPEATABLE_READ可重复读
SERIALIZABLE序列化操作
DEFAULT默认,根据数据库隔离级别自动选择,
4.spring aop应用
aop编程优点:可以动态将一个组件功能切入到指定的目标方法上。可以使结构更加灵活,也能实现组件重复利用。
aop编程:更注重于业务逻辑隔离,将一些共通处理逻辑和传统处理逻辑解耦。
例如事务处理,日志记录,异常处理等等。
适用环境:
--共通处理逻辑
--调用时机相同
例子,用xml配置方式,往controller上加方法:
1.新建了一个aspect包(非必须)
2.包里新建一个类,然后新建一个clogger方法。表示加上日志功能。
3.spring的文件里加配置,把需要aop的controller加上第二步类里的方法
package org.alexhe.note.aspect;
public class NoteLogger {
public void clogger(){
System.out.println("进入Controller处理");
}
}
spring的配置:
<!-- aop示例 -->
<bean id="noteLogger" class="org.alexhe.note.aspect.NoteLogger"></bean>
<aop:config>
<!-- 把上面的noteLogger定义为切面组件 -->
<aop:aspect ref="noteLogger">
<!-- 什么时候,向哪些方法上切入 --><!-- 在controler包及其子包下,所有执行的方法前,加入clogger方法 -->
<aop:before method="clogger" pointcut="within(org.alexhe.note.controller..*)"/>
</aop:aspect>
</aop:config>
例子,用注解方式,往service层加方法:
spring配置不用上面这一坨,只要加上:
<!-- 开启aop注解支持,@Aspect,@通知标记 -->
<aop:aspectj-autoproxy />
java类:
package org.alexhe.note.aspect;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
@Component//扫描,将组件扫描到Spring容器
@Aspect//将当前组件设置为切面组件
public class ServiceLogger {
@Before("within(org.alexhe.note.service..*)")//service下面所有方法加入这个slooger方法
public void slogger(){
System.out.println("进入service方法");
}
}
=====AOP应用=====
a。要切入什么功能
b。要切入的时机,什么时候切入,通知。
前置通知,在原有方法前插入新功能。@Before
后置通知,在执行完原有方法后,调入新的切面方法。@AfterReturning
异常通知,在原有方法出异常了,调入新的切面方法。@AfterThrowing
最终通知,不管有没有异常,最终都要走他。@After
环绕通知=前置+后置
try{
前置通知@Before
//目标方法处理
后置通知@AfterReturning
}catch(){
异常通知@AfterThrowing
}finally{
最终通知@After
}
c。往那些组件方法切入-->切入点
--类型限定表达式
within(类型)
与类型匹配的组件都是目标
within(org.service.UserService)
within(org.service.*) 仅限于当前包下
within(org.service..*) 当前包和子包下
--方法限定表达式
execution(修饰符 返回类型 方法名(参数) 抛出异常) 返回类型和方法名参数是必须的,其他可以省略
execution(* find*(..)) 必须是find开头的方法,参数返回值不限制
execution(* org.service.UserService.regist*(..))
execution(* org.service..*.*(..))
上述表达式可以使用 !,&&,|| 运算符连接。
案例:将异常信息写入文件
package org.alexhe.note.aspect;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.AfterThrowing;
import org.springframework.stereotype.Component;
@Component//扫描,将组件扫描到Spring容器
@Aspect//将当前组件设置为切面组件
public class ExceptionLogger {
@AfterThrowing(throwing="e",pointcut="within(org.alexhe.note.service..*)")//service下面所有方法加入这个log方法
public void log(Exception e){
System.out.println(e);
}
}
spring事务管理方式,aop的更多相关文章
- spring 事务管理方式及配置
1.Spring声明式事务配置的五种方式 前段时间对Spring的事务配置做了比较深入的研究,在此之前对Spring的事务配置虽说也配置过,但是一直没有一个清楚的认识.通过这次的学习发觉Spring的 ...
- Spring 事务管理tx,aop
spring tx:advice事务配置 2016年12月21日 17:27:22 阅读数:7629 http://www.cnblogs.com/rushoooooo/archive/2011/08 ...
- spring事务管理方式大全
http://blog.csdn.net/baibinboss/article/details/64922472
- Spring事务管理详解_基本原理_事务管理方式
1. 事务的基本原理 Spring事务的本质其实就是数据库对事务的支持,使用JDBC的事务管理机制,就是利用java.sql.Connection对象完成对事务的提交,那在没有Spring帮我们管理事 ...
- Spring事务管理(编码式、配置文件方式、注解方式)
1.事务(https://www.cnblogs.com/zhai1997/p/11710082.html) (1)事务的特性:acdi (2)事务的并发问题:丢失修改,脏读,不可重复读 (3)事务的 ...
- 【Java EE 学习 52】【Spring学习第四天】【Spring与JDBC】【JdbcTemplate创建的三种方式】【Spring事务管理】【事务中使用dbutils则回滚失败!!!??】
一.JDBC编程特点 静态代码+动态变量=JDBC编程. 静态代码:比如所有的数据库连接池 都实现了DataSource接口,都实现了Connection接口. 动态变量:用户名.密码.连接的数据库. ...
- 事务管理(下) 配置spring事务管理的几种方式(声明式事务)
配置spring事务管理的几种方式(声明式事务) 概要: Spring对编程式事务的支持与EJB有很大的区别.不像EJB和Java事务API(Java Transaction API, JTA)耦合在 ...
- Spring事务管理的四种方式(以银行转账为例)
Spring事务管理的四种方式(以银行转账为例) 一.事务的作用 将若干的数据库操作作为一个整体控制,一起成功或一起失败. 原子性:指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不 ...
- Spring事务管理之几种方式实现事务
1.事务认识 大家所了解的事务Transaction,它是一些列严密操作动作,要么都操作完成,要么都回滚撤销.Spring事务管理基于底层数据库本身的事务处理机制.数据库事务的基础,是掌握Spring ...
随机推荐
- day09 详解内存管理机制
""" 今日内容:详解内存管理 1.引用计数 在内存中为了对变量的值进行标记从而方便管理,采用引用计数的方式对变量进行标记. (1)如果变量的值被引用一次,那么该变量的引 ...
- The Ethereum devp2p and discv4 protocol Part II
描述 本文章主上下两篇 上篇:讲述以太坊devp2p与disc4节点发现协议 下篇:实践篇,实现如何获取以太坊所有节点信息(ip,port,nodeId,client) 正文 本片为下篇:实践篇,主要 ...
- 感受野RF的计算
参考博客:https://blog.csdn.net/wgx571859177/article/details/80983043 设第N层的感受野为N_RF,卷积核尺寸为kernel_size,步长为 ...
- Python爬虫基础之requests
一.随时随地爬取一个网页下来 怎么爬取网页?对网站开发了解的都知道,浏览器访问Url向服务器发送请求,服务器响应浏览器请求并返回一堆HTML信息,其中包括html标签,css样式,js脚本等.我们之前 ...
- typescript解决深度拷贝中循环引用引起的死循环
循环引用有人说就是一种不健康的状态,即你中有我,我中有你 hasObj: any = []; deepCopy(data: any) { this.hasObj.push(data); //最终就是返 ...
- java类(Class)的概念;对象的概念,声明类的属性 和方法,局部变量和成员变量,面向对象编程思维,抽象的概念
类(Class)的概念 类是对一组具有相同特征和行为的对象的抽象描述. 理解: [1] 类包含了两个要素:特性和行为 => 同一类事物具有相同的特征和行为. [2] 类是一个群体性概念.例如:网 ...
- 详解Django的CSRF认证
1.csrf原理 csrf要求发送post,put或delete请求的时候,是先以get方式发送请求,服务端响应时会分配一个随机字符串给客户端,客户端第二次发送post,put或delete请求时携带 ...
- win10下caffe安装与mnist测试实验注意点
caffe安装 安装内容:win10教育版+anaconda2+python(无gpu版本) 安装教程:主要依照三年一梦教程:https://www.cnblogs.com/king-lps/p/65 ...
- python Django2.X,报错 ‘learning_logs ’is not a registered namespace,如何解决?
自己也查阅了自己出现了的问题,其中就有这么个按照书中来写的代码但是Django却是提示了 ‘learning_logs ’is not a registered namespace. 然后错误提示可 ...
- Docker使用Mysql镜像命令
本次使用的环境是win10下的hyper-v安装的CentOS7系统 控制台输入命令: docker run -p 3307:3306 --name mysql01 -v $PWD/conf:/etc ...