多个事务方法相互调用时,事务如何在这些方法间传播。
Spring中对于事务的传播行为定义了七种类型分别是:
REQUIRED 默认
SUPPORTS 支持
MANDATORY 强制
REQUIRES_NEW 新建
NOT_SUPPORTED 不支持
NEVER 从不
NESTED 嵌套
7种传播机制详解:
插入A:
public class AService {
public void A(String name) {
userService.insertName("A-" + name);
}
}
插入B:
public class BService {
public void B(String name) {
userService.insertName("B-" + name);
}
}
//创建两个方法,main方法调用test方法
public void mainTest(String name) {
A(a1); // 存入a1
childTest(name);
}
public void childTest(String name) {
B(b1);// 存入b1
throw new RuntimeException();
B2(b2);// 存入 b2
}
如果两者都没有使用事务,则a1,b1插入成功,b2不成功。
如果当前不存在事务,就新建一个事务。如果存在事务,就加入到当前事务。这是一个默认的事务。
(1)在test方法前加注解 @Transactional(propagation = Propagation.REQUIRED)
使其为默认事务。
测试代码中a1添加正常,b1由于发生异常回滚,故b1添加失败。
(2)在test和main方法前加注解 @Transactional(propagation = Propagation.REQUIRED)
使其为默认事务。
测试代码中a1由于属于同一事务,test方法异常而发生回滚,b1由于发生异常也回滚,故a1,b1都添加失败。
如果当前没有事务,则以非事务的方式运行。如果存在事务,就加入到当前事务。
(1)childTest 添加事务,传播属性设置为 SUPPORTS
如果没有事务,就以非事务的方式运行。表明两个方法都没有使用事务,没有事务的话,a1、b1 都添加成功。
(2)再给main添加事务,运行时存在事务,故test的事务加入到main中,那么test发生异常,则a1,b1都回滚,故a1,b1添加不成功。
如果存在事务,就加入到当前事务。如果不存在事务,就报错。
(1)childTest 添加事务,传播属性设置为 SUPPORTS,而执行main时该方法不存在事务,故直接报错。
(2)再给main添加事务,运行时存在事务,故test的事务加入到main中,那么test发生异常,则a1,b1都回滚,故a1,b1添加不成功。
创建一个新的事务。如果存在事务,就将事务挂起。
(1)childTest 添加事务,设置传播属性为 REQUIRES_NEW
mainTest 不存在事务,a1 添加成功,childTest 新建了一个事务,报错,回滚 b1。所以 a1 添加成功,b1 添加失败。
无论是否存在当前事务,都是以非事务的方式运行。
main和test都以非事务运行,故a1,b1添加成功。
main和test都以非事务运行,故a1,b1添加成功。
如果设置main为required,则b1添加成功,异常抛给上层main,a1回滚,a1添加失败。
不使用事务,如果存在事务,就抛出异常
Test不使用事务,main也不使用事务,故a1,b1添加成功,b2添加失败。
main 存在事务,导致 Test 报错,b1添加失败,Test 抛错到 main,a1 添加失败。
如果当前事务存在,就运行一个嵌套事务。如果不存在事务,就和 REQUIRED 一样新建一个事务
(1)在Test 设置 NESTED 传播属性,相当于新建一个事务,所以 b1 添加失败, main 没有事务,a1 添加成功。
(2)设置 main 传播属性为 REQUIRED,新建一个事务,并在方法最后抛出异常。 Test 设置属性为 NESTED
Test 是一个嵌套的事务,当主事务的抛出异常时,嵌套事务也受影响,即 a1、b1 和 b2 都添加失败
核心容器提供Spring框架的基本功能。spring以bean的方式组织和管理Java应用的各个组件及其关系,spring使用BeanFactory来产生和管理Bean,是工厂模式的实现,BeanFactory使用控制反转(IoC)模式将应用的配置和依赖性规范与实际的应用程序代码分开
Spring上下文是一个配置文件,向spring提供上下文信息,spring上下文包括企业服务、、、、
AOP(Aspect Oriented Programming)
通过配置管理特性,SpringAOP模块直接将面向方法的编程功能集成在了Spring框架中,Spring管理的任何对象都支持AOP,SpringAOP模块基于Spring的应用程序中的对象提供了事务管理服务,通过使用SpringAOP,不用依赖EJB组件,就可以将声明性事务管理集成在应用程序中
Dao(Data Access Object)
JDBC、DAO的抽象层,提供了有意义的异常层次结构实现,可用该结构来管理异常处理,和不同数据库提供商抛出的错误信息,异常层次结构简化了错误处理,并且极大的降低了需要编写的代码数量,比如打开和关闭链接。
ORM(Object Relational Mapping)
Spring插入了若干个ORM框架,提供了ORM对象的关系工具,其中包括Hibernate,JDO和IBatisSQL Map等,所有这些都遵从Spring的通用事务和DAO异常层次结构
web上下文模块建立应用程序上下文模块之上,基于web的应用程序提供了上下文,所以spring框架支持与Struts集成,web模块还简化了处理多部分请求以及将请求参数绑定到域对象的工作
MVC(Model View Controller)
MVC框架是一个全功能的构建Web应用程序的MVC实现,通过策略接口,MVC框架编程高度可配置的,MVC容纳了大量视图技术,其中包括JSP,POI等,模型由JavaBean来构成,存放于m当中,而视图是一个接口,负责实现模型,控制器表示逻辑代码,由c的事情。spring框架的功能可以用在任何J2EE服务器当中,大多数功能也适用于不受管理的环境,spring的核心要点就是支持不绑定到特定J2EE服务的可重用业务和数据的访问对象,毫无疑问这样的对象可以在不同的J2EE环境,独立应用程序和测试环境之间重用。
两者都是装入bean定义信息,装配bean,根据需要分发bean。但是ApplicationContext提供更多功能,它提供了bean工厂所没有的解析信息文本工具,包括对国际化的支持,提供了载入文件资源的通用方法,如载入图片,它可以用注册为监听器的bean发送事件。另外一个很重要的区别是单例bean被载入的方式不一样。bean工厂延迟载入所有的bean,直到getbean方法被调用,才被创建。而ApplicationContext会预装入所有的单例bean,确保需要的时候单例bean都已经准备好了,这样我们的应用就不需要等待这些单例bean被创建。
开发者通过在相应的类,方法或属性上使用注解的方式,直接组件类中进行配置,而不是使用xml表述bean的装配关系、
注解装配在默认情况下是不开启的,为了使用注解装配,我们必须在Spring配置文件中配置