Spring 使用注解方式进行事务管理
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring 使用注解方式进行事务管理相关的知识,希望对你有一定的参考价值。
参考技术A使用步骤:
事务的传播行为和隔离级别
大家在使用spring的注解式事务管理时,对事务的传播行为和隔离级别可能有点不知所措,下边就详细的介绍下以备方便查阅。
事物注解方式: @Transactional
当标于类前时, 标示类中所有方法都进行事物处理 , 例子:
当类中某些方法不需要事物时:
事物超时设置:
@Transactional(timeout=30) //默认是30秒
事务隔离级别:
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
读取未提交数据(会出现脏读, 不可重复读) 基本不使用
@Transactional(isolation = Isolation.READ_COMMITTED)
读取已提交数据(会出现不可重复读和幻读)
@Transactional(isolation = Isolation.REPEATABLE_READ)
可重复读(会出现幻读)
@Transactional(isolation = Isolation.SERIALIZABLE)
串行化
mysql: 默认为REPEATABLE_READ级别
SQLSERVER: 默认为READ_COMMITTED
脏读 : 一个事务读取到另一事务未提交的更新数据
不可重复读 : 在同一事务中, 多次读取同一数据返回的结果有所不同, 换句话说,
后续读取可以读到另一事务已提交的更新数据. 相反, "可重复读"在同一事务中多次
读取数据时, 能够保证所读数据一样, 也就是后续读取不能读到另一事务已提交的更新数据
幻读 : 一个事务读到另一个事务已提交的insert数据
@Transactional注解中常用参数说明
续表)
注意的几点:
1 @Transactional 只能被应用到public方法上, 对于其它非public的方法,如果标记了@Transactional也不会报错,但方法没有事务功能.
2用 spring 事务管理器,由spring来负责数据库的打开,提交,回滚.默认遇到运行期例外(throw new RuntimeException("注释");)会回滚,即遇到不受检查(unchecked)的例外时回滚;而遇到需要捕获的例外(throw new Exception("注释");)不会回滚,即遇到受检查的例外(就是非运行时抛出的异常,编译器会检查到的异常叫受检查例外或说受检查异常)时,需我们指定方式来让事务回滚 要想所有异常都回滚,要加上 @Transactional( rollbackFor=Exception.class,其它异常) .如果让unchecked例外不回滚: @Transactional(notRollbackFor=RunTimeException.class)
如下:
@Transactional(rollbackFor=Exception.class) //指定回滚,遇到异常Exception时回滚
public void methodName()
throw new Exception("注释");
@Transactional(noRollbackFor=Exception.class)//指定不回滚,遇到运行期例外(throw new RuntimeException("注释");)会回滚
public ItimDaoImpl getItemDaoImpl()
throw new RuntimeException("注释");
3、@Transactional 注解应该只被应用到 public 可见度的方法上。 如果你在 protected、private 或者 package-visible 的方法上使用 @Transactional 注解,它也不会报错, 但是这个被注解的方法将不会展示已配置的事务设置。
4、@Transactional 注解可以被应用于接口定义和接口方法、类定义和类的 public 方法上。然而,请注意仅仅 @Transactional 注解的出现不足于开启事务行为,它仅仅 是一种元数据,能够被可以识别 @Transactional 注解和上述的配置适当的具有事务行为的beans所使用。上面的例子中,其实正是 元素的出现 开启 了事务行为。
5、Spring团队的建议是你在具体的类(或类的方法)上使用 @Transactional 注解,而不要使用在类所要实现的任何接口上。你当然可以在接口上使用 @Transactional 注解,但是这将只能当你设置了基于接口的代理时它才生效。因为注解是 不能继承 的,这就意味着如果你正在使用基于类的代理时,那么事务的设置将不能被基于类的代理所识别,而且对象也将不会被事务代理所包装(将被确认为严重的)。因 此,请接受Spring团队的建议并且在具体的类上使用 @Transactional 注解。
Spring管理Bean(XML与注解方式)
文章目录
什么是Bean管理?
bean管理其实指的是这两个操作:
- 创建对象
- 注入属性
Spring是如何管理Bean的?
Spring通过IoC容器来管理Bean,我们可以通过XML配置或者注解配置,来指导IoC容器对Bean的管理。因为注解配置比XML配置方便很多,所以现在大多时候会使用注解配置的方式。
下面分别来看一下:
环境准备
新建maven项目,引入依赖
<!-- 引入依赖 -->
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.12</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
基于xml方式注入属性
第一种注入方式:使用set方式进行注入。
实现步骤如下所示:
创建类,定义属性和对应的set方法;
public class Book
//创建属性
private String bname;
private String bauthor;
//创建属性对应的set方法
public void setBname(String bname)
this.bname = bname;
public void setBauthor(String bauthor)
this.bauthor = bauthor;
在spring配置文件配置对象创建(<bean>
标签),配置属性注入(<bean>
标签内部的<property>
标签)。注入属性在创建对象的基础之上完成,先创建对象,在注入属性。
<!-- set方法注入属性-->
<bean id = "book" class="com.yyl.entity.Book">
<!-- 使用property完成属性注入
name: 类里面属性名称
value:向属性注入的值
-->
<property name="bname" value="从你的全世界路过"></property>
<property name="bauthor" value="张嘉佳"></property>
</bean>
对xml方式使用set进行注入的测试:
@Test
public void SetterBean()
// 1. 加载spring 配置文件
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
// 2. 获取配置创建的对象
Book book = context.getBean("book", Book.class);
System.out.println(book.hashCode());
System.out.println(book.toString());
测试结果:
第二种注入方式:使用有参数的构造函数进行注入
实现步骤如下所示:
创建类,定义属性,创建属性对应的有参数构造方法
public class Orders
//属性
private String name;
private String address;
//多参数构造函数
public Orders(String name, String address)
this.name = name;
this.address = address;
在spring配置文件中进行配置:
<!-- 使用有参构造函数注入属性-->
<bean id="orders" class="com.yyl.entity.Orders">
<constructor-arg name="name" value="衣架"></constructor-arg>
<constructor-arg name ="address" value="china"></constructor-arg>
</bean>
对xml方式使用有参构造注入的测试:
@Test
public void ConstructorBean()
// 1. 加载spring 配置文件
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
// 2. 获取配置创建的对象
Orders orders = context.getBean("orders", Orders.class);
System.out.println(orders.hashCode());
System.out.println(orders.toString());
测试结果:
注解配置
以下是管理Bean时常用的一些注解:
-
@ComponentScan用于声明扫描策略,通过它的声明,容器就知道要扫描哪些包下带有声明的类,也可以知道哪些特定的类是被排除在外的。
-
@Component、@Repository、@Service、@Controller用于声明Bean,它们的作用一样,但是语义不同。@Component用于声明通用的Bean,@Repository用于声明DAO层的Bean,@Service用于声明业务层的Bean,@Controller用于声明视图层的控制器Bean,被这些注解声明的类就可以被容器扫描并创建。
-
@Autowired、@Qualifier用于注入Bean,即告诉容器应该为当前属性注入哪个Bean。其中,@Autowired是按照Bean的类型进行匹配的,如果这个属性的类型具有多个Bean,就可以通过@Qualifier指定Bean的名称,以消除歧义。
-
@Scope用于声明Bean的作用域,默认情况下Bean是单例的,即在整个容器中这个类型只有一个实例。可以通过@Scope注解指定prototype值将其声明为多例的,也可以将Bean声明为session级作用域、request级作用域等等,但最常用的还是默认的单例模式。
-
@PostConstruct、@PreDestroy用于声明Bean的生命周期。其中,被@PostConstruct修饰的方法将在Bean实例化后被调用,@PreDestroy修饰的方法将在容器销毁前被调用。
半注解式代码
配置文件中 配置的扫描不再用<bean>
标签,而是扫描包下注解:
<!-- 扫描注入-->
<context:component-scan base-package="包"></context:component-scan>
下面我们进行测试:
修改xml文件:
<!--配置扫面-->
<!--配置扫描带有四大注解类:@Controller、@Service、@Repository、@Component,交给spring统一管理-->
<context:component-scan base-package="com.yyl"></context:component-scan>
编写User类
package com.yyl.entity;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component(value = "user")
public class User
@Value("18")
private int age;
@Value("玉如梦")
private String name;
@Override
public String toString()
return "User" +
"age=" + age +
", name='" + name + '\\'' +
'';
编写测试代码:
@Test
public void AnnotationBean()
// 1. 加载spring 配置文件
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
// 2. 获取配置创建的对象
User user = context.getBean("user", User.class);
System.out.println(user);
运行结果:
纯注解代码
编写配置类:
package com.yyl.config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration//声明配置类
@ComponentScan(value = "com.yyl") //扫描具体的包
public class SpringConfig
编写测试代码:
@Test
public void AnnotationBean2()
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
User user = context.getBean("user",User.class);
System.out.println(user);
运行结果:
以上是关于Spring 使用注解方式进行事务管理的主要内容,如果未能解决你的问题,请参考以下文章