Spring事务配置的五种方式
spring MVC原理及配置

spring MVC原理及配置springmvc原理及配置springmvc原理及配置1.springmvc详述:springmvc就是spring提供更多的一个强悍而有效率的web框架。
借助注释,springmvc提供更多了几乎就是pojo的研发模式,使控制器的研发和测试更加直观。
这些控制器通常不轻易处置命令,而是将其委托给spring上下文中的其他bean,通过spring的倚赖转化成功能,这些bean被转化成至控制器中。
springmvc主要由dispatcherservlet、处理器映射、处理器(控制器)、视图解析器、视图组成。
他的两个核心是两个核心:处理器映射:选择使用哪个控制器来处理请求视图解析器:选择结果应该如何渲染通过以上两点,springmvc确保了如何挑选掌控处置命令和如何挑选视图展现出输入之间的松耦合。
2.springmvc运行原理这里写图片描述(2)找寻处理器:由dispatcherservlet控制器查阅一个或多个handlermapping,找出处置命令的controller。
(3)调用处理器:dispatcherservlet将请求提交到controller。
(4)(5)调用业务处置和回到结果:controller调用业务逻辑处置后,回到modelandview。
3.springmvc接口解释(1)dispatcherservlet接口:spring提供的前端控制器,所有的请求都有经过它来统一分发。
在dispatcherservlet将请求分发给springcontroller 之前,需要借助于spring提供的handlermapping定位到具体的controller。
(2)handlermappingUSB:能够完成客户请求到controller映射。
(3)controller接口:须要为mammalian用户处置上述命令,因此同时实现controllerUSB时,必须确保线程安全并且可以器重。
Spring核心技术详解

Spring核⼼技术详解⼀、Sring简介Spring是⼀个分层的Java SE/EE应⽤⼀站式的轻量级开源框架。
Spring核⼼是IOC和AOP。
Spring主要优点包括:⽅便解耦,简化开发,通过Spring提供的IoC容器,我们可以将对象之间的依赖关系交由Spring进⾏控制,避免硬编码造成的程序耦合度⾼。
AOP编程的⽀持,通过Spring提供的AOP功能,⽅便进⾏⾯向切⾯编程。
声明式事务的⽀持,在Spring中,我们可以从单调烦闷的事务管理代码中解脱出来,通过声明式⽅式灵活地进⾏事务的管理,提⾼开发效率和质量。
⽅便程序的测试,可以⽤⾮容器依赖的编程⽅式进⾏⼏乎所有的测试⼯作。
⽅便集成各种优秀框架,Spring提供了对各种优秀框架的直接⽀持。
⼆、Spring体系结构如下图所⽰,整个spring框架按其所属功能可以划分为五个主要模块,这五个模块⼏乎为企业应⽤提供了所需的⼀切,从持久层、业务层到表现层都拥有相应的⽀持,这就是为什么称Spring是⼀站式框架的原因。
核⼼模块(Core Container) Spring的核⼼模块实现了IoC的功能,它将类和类之间的依赖从代码中脱离出来,⽤配置的⽅式进⾏依赖关系描述。
由IoC容器负责类的创建,管理,获取等。
BeanFactory接⼝是Spring框架的核⼼接⼝,实现了容器很多核⼼的功能。
Context模块构建于核⼼模块之上,扩展了BeanFactory的功能,包括国际化,资源加载,邮件服务,任务调度等多项功能。
ApplicationContext是Context模块的核⼼接⼝。
表达式语⾔(Expression Language)是统⼀表达式语⾔(EL)的⼀个扩展,⽀持设置和获取对象属性,调⽤对象⽅法,操作数组、集合等。
使⽤它可以很⽅便的通过表达式和Spring IoC容器进⾏交互。
AOP模块Spring AOP模块提供了满⾜AOP Alliance规范的实现,还整合了AspectJ这种AOP语⾔级的框架。
springboot之手动控制事务

springboot之⼿动控制事务 ⼀、事务的重要性,相信在实际开发过程中,都有很深的了解了。
但是存在⼀个问题我们经常在开发的时候⼀般情况下都是⽤的注解的⽅式来进⾏事务的控制,说⽩了基于spring的7种事务控制⽅式来进⾏事务的之间的协调。
⼆、spring的7中事务传播⾏为Propagation.REQUIRED代表当前⽅法⽀持当前的事务,且与调⽤者处于同⼀事务上下⽂中,回滚统⼀回滚(如果当前⽅法是被其他⽅法调⽤的时候,且调⽤者本⾝即有事务),如果没有事务,则⾃⼰新建事务,Propagation.SUPPORTS代表当前⽅法⽀持当前的事务,且与调⽤者处于同⼀事务上下⽂中,回滚统⼀回滚(如果当前⽅法是被其他⽅法调⽤的时候,且调⽤者本⾝即有事务),如果没有事务,则该⽅法在⾮事务的上下⽂中执⾏Propagation.MANDATORY代表当前⽅法⽀持当前的事务,且与调⽤者处于同⼀事务上下⽂中,回滚统⼀回滚(如果当前⽅法是被其他⽅法调⽤的时候,且调⽤者本⾝即有事务),如果没有事务,则抛出异常Propagation.REQUIRES_NEW创建⼀个新的事务上下⽂,如果当前⽅法的调⽤者已经有了事务,则挂起调⽤者的事务,这两个事务不处于同⼀上下⽂,如果各⾃发⽣异常,各⾃回滚Propagation.NOT_SUPPORTED该⽅法以⾮事务的状态执⾏,如果调⽤该⽅法的调⽤者有事务则先挂起调⽤者的事务Propagation.NEVER该⽅法以⾮事务的状态执⾏,如果调⽤者存在事务,则抛出异常Propagation.NESTED如果当前上下⽂中存在事务,则以嵌套事务执⾏该⽅法,也就说,这部分⽅法是外部⽅法的⼀部分,调⽤者回滚,则该⽅法回滚,但如果该⽅法⾃⼰发⽣异常,则⾃⼰回滚,不会影响外部事务,如果不存在事务,则与PROPAGATION_REQUIRED⼀样 三、数据库四⼤特性和MySQL事务的隔离级别 1)四⼤特性 a、原⼦性(Atomicity) 原⼦性是指事务包含的所有操作要么全部成功,要么全部失败回滚。
实验一Spring环境配置

<beansxmlns="/schema/beans"
xmlns:xsi="/2001/XMLSchema-instance"
xsi:schemaLocation="/schema/beans
传统J2EE应用的开发效率低,应用服务器厂商对各种技术的支持并没有真正统一,导致J2EE的应用没有真正实现Write Once及Run Anywhere的承诺。Spring作为开源的中间件,独立于各种应用服务器,甚至无须应用服务器的支持,也能提供应用服务器的功能,如声明式事务、事务处理等。
Spring致力于J2EE应用的各层的解决方案,而不是仅仅专注于某一层的方案。可以说Spring是企业应用开发的“一站式”选择,并贯穿表现层、业务层及持久层。然而,Spring并不想取代那些已有的框架,而是与它们无缝地整合。
}
publicvoidrecharge(){
System.out.println("您好"+user.getAccount()+"用户,你的账户充值成功!");
System.out.println("充值金额为:"+user.getMoney());
}
publicvoidread(){
try(BufferedReader reader =newBufferedReader(
(三)Spring由哪些模块组成?它们分别有些什么作用?
Spring 框架是一个分层架构,由 7 个定义良好的模块组成。Spring模块构建在核心容器之上,核心容器定义了创建、配置和管理 bean 的方式,如图所示:
高级Java工程师面试题及答案

高级Java工程师面试题选择题各2分共44分1.下列说法正确的是A. Java语言不区分大小写B. Java程序以类为基本单位C. JVM为Java虚拟机JVM的英文缩写D. 运行Java程序需要先安装JDK答案:B,C,D2.下列说法中错误的是A. Java语言是编译执行的B. Java中使用了多进程技术C. Java的单行注视以//开头D. Java语言具有很高的安全性答案:A,B3.下面不属于Java语言特点的一项是A. 安全性B. 分布式C. 移植性D. 编译执行答案:D4.下列语句中,正确的项是A . int $ e,a,b=10;B. char c,d=’a’;C. float e=0.0d;D. double c=0.0f;答案ABD5.一个int 类型的常量和一个byte类型常量做减法,结果的类型是A. intB. byteC. charD. float答案A6.下列程序段的输出结果是public class Expressions{void printExpr(){int x=3,y=4,z=5;System.out.println(x+y+z);}}A. xyzB. x+y+zC. 12D. 9答案C7.下列关于for循环和while循环的说法中哪些是不正确的?A. for循环能实现的操作,while循环也都能实现B. for循环判断条件一般是非程序结果C. while循环判断条件一般是程序结果D. 两种循环结构中都必须有循环体,循环体不能为空答案ABC8.以下程序段执行后的K值为int x=10; y=34;k=(x<y)?y:x;A. 10B. 34C. 10D. 44答案B9.下列不属于Java语言流程控制结构是A.分支语句B.条转语句C.循环语句D.赋值语句E.答案D10.设定义语句:int a[ ]={43,44,45};则下面对此语句的叙述正确的是A.定义一个名为a的一维数组B.a数组有3个元素C.a数组的元素的下标为1~3D.数组中的每一个元素都是整型E.答案ABD11.运行以下代码public class Person{int array[]=new int[10];public static void main(String args[]){System.out.println(array [1]);}}正确的是A.编译时将产生错误B.编译时正确,运行时将产生错误C.输出零D.输出空答案A12.执行完下面语句int[ ]x = new int[20]; 后,说法正确的是A.x[19]为0B.x[19]未定义C.x[20]为0D.x[0]为空答案A13.设tmp是一个数组类成员,以下声明并初始化一个4个元素的数组选项A.int tmp[]={1,2,3,4};B.int tmp[]=new int[5];C.int tmp[]=new int(5);D.int tmp[];答案A14.设定义:String s=”cake”,下面不合法的有A.s=s. toUpperCase();B.char c=s[1];C.int len=s.length;D.s=s.trim();答案BC15.设String s1=”Hello”;String s2=”World”;以下方法用来得到字符串“Hello World”有A.s2+s1;B.s1.concat(s2);C.s1.append(s2);D.s1.concate(s2);答案B16.下面哪一个是Java最基本的元素A. 接口B. 方法C. 包D. 对象答案:D17.如果Cake.java、Ball.java这两个类总共包含有8个方法,则编译后会产生多少个字节码文件A. 12B. 10C. 2D. 1答案:C18.下面关于抽象类的理解,错误的是A. 构造方法可以声明为抽象类型B. 抽象方法必须被子类的方法覆盖C. 不允许实现抽象方法D. 方法声明中,static 和abstract不能同时存在答案:A19.编译Java程序时编译器提示找不到要编译的代码,这种错误通常可能是A. 文件名拼写错误B. 没有导入相应的包C. 文件名不是.javaD. 源文件不在Java搜索路径中答案:A,C,D20.捕获异常应该使用下列哪个子句A. throwB. catchC. finallyD. throws答案:B21.下列哪一项不属于finally语句的工作A. 关闭数据库B. 释放资源C. 关闭文件D.分配资源答案:D22.下面哪些需要异常处理机制A. 编译出错B. 方法、类中抛出的异常C. 使系统从故障中恢复D. 程序因不可避免的原因产生错误答案:B,C,D简述题每题3分共18分(1)用final声明属性、方法和类时,被声明的属性、方法和类表现出哪些特性?下面的实例正确吗?如果不正确,请说明原因?实例:final Test t = new Test();t.setName(“Jack”);答:final 用于声明属性,方法和类,分别表示属性不可变,方法不可覆盖,类不可继承。
【SpringFramework】Spring入门教程(三)使用注解配置

【SpringFramework】Spring⼊门教程(三)使⽤注解配置本⽂主要介绍四个⽅⾯:(1) 注解版本IOC和DI(2) Spring纯注解(3) Spring测试(4) SpringJDBC - Spring对数据库的操作使⽤注解配置Spring⼊门说在前⾯学习基于注解的IoC配置,⼤家脑海⾥⾸先得有⼀个认知,即注解配置和xml配置要实现的功能都是⼀样的,都是要降低模块间的耦合度。
仅仅只是配置的形式不⼀样。
关于实际的开发中到底使⽤xml还是注解,每家公司有着不同的使⽤习惯。
所以这两种配置⽅式我们都需要掌握。
基于注解配置的⽅式也已经逐渐代替xml配置。
所以我们必须要掌握使⽤注解的⽅式配置Spring。
配置步骤注意:如果使⽤Eclipse需要先安装了STS插件,或者使⽤STS开发⼯具创建项⽬。
本⽂使⽤IDEA进⾏演⽰。
1.2.1. 第⼀步:拷贝必备jar包到⼯程的lib⽬录。
注意:在基于注解的配置中,我们还要多拷贝⼀个aop的jar包。
如下图:1.2.2. 第⼆步:在类的根路径下创建⼀个任意名称的xml⽂件(不能是中⽂)注意:基于注解整合时,Spring配置⽂件导⼊约束时需要多导⼊⼀个context命名空间下的约束。
<?xml version="1.0" encoding="UTF-8"?><beans xmlns="/schema/beans"xmlns:xsi="/2001/XMLSchema-instance"xmlns:context="/schema/context"xsi:schemaLocation="/schema/beans/schema/beans/spring-beans.xsd/schema/context/schema/context/spring-context.xsd"></beans>1.2.3. 第⼆步:创建⼀个服务类创建⼀个测试的服务类,并且加⼊使⽤@Component注解,声明该类允许注⼊到Spring容器package org.cjw.service;import ponent;/*使⽤注解配置时,需要将Spring框架启动就创建对象的类表⽰为组件类表⽰组件类使⽤@Component注解*/@Componentpublic class CustomerService {public void save() {System.out.println("-保存数据-");}}1.2.4. 第四步在spring的配置⽂件加⼊扫描注解<?xml version="1.0" encoding="UTF-8"?><beans xmlns="/schema/beans"xmlns:xsi="/2001/XMLSchema-instance"xmlns:context="/schema/context"xsi:schemaLocation="/schema/beans/schema/beans/spring-beans.xsd/schema/context/schema/context/spring-context.xsd"><!-- 声明扫描包及其⼦包的类,如果发现有组件注解的类,就创建对象并加⼊到容器中去 --><context:component-scan base-package="org.cjw" /></beans>1.2.5. 第五步:测试调⽤代码package org.cjw.test;import org.cjw.service.CustomerService;import org.junit.Test;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;public class CustomerServiceTest {@Testpublic void testSave() {ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");CustomerService customerService = context.getBean(CustomerService.class);customerService.save();}}--测试结果,如果可以调⽤服务⽅法,测试成功。
《Java EE企业级应用开发教程(Spring+Spring MVC+MyBatis)》_课后习题

第一章【思考题】1、请简述Spring框架的优点。
2、请简述什么是Spring的IoC和DI。
【答案】1、Spring框架的优点如下:(1)非侵入式设计:Spring是一种非侵入式(non-invasive)框架,它可以使应用程序代码对框架的依赖最小化。
(2)方便解耦、简化开发:Spring就是一个大工厂,可以将所有对象的创建和依赖关系的维护工作都交给Spring容器管理,大大的降低了组件之间的耦合性。
(3)支持AOP:Spring提供了对AOP的支持,它允许将一些通用任务,如安全、事务、日志等进行集中式处理,从而提高了程序的复用性。
(4)支持声明式事务处理:只需要通过配置就可以完成对事务的管理,而无需手动编程。
(5)方便程序的测试:Spring提供了对Junit4的支持,可以通过注解方便的测试Spring 程序。
(6)方便集成各种优秀框架:Spring不排斥各种优秀的开源框架,其内部提供了对各种优秀框架(如:Struts、Hibernate、MyBatis、Quartz等)的直接支持。
(7)降低了Java EE API的使用难度:Spring对Java EE开发中非常难用的一些API (如:JDBC、JavaMail等),都提供了封装,使这些API应用难度大大降低。
2、IoC的全称是Inversion of Control,中文名称为控制反转。
控制反转就是指在使用Spring框架之后,对象的实例不再由调用者来创建,而是由Spring容器来创建,Spring 容器会负责控制程序之间的关系,而不是由调用者的程序代码直接控制。
这样,控制权由应用代码转移到了Spring容器,控制权发生了反转。
DI的全称是Dependency Injection,中文称之为依赖注入。
它与控制反转(IoC)的含义相同,只不过这两个称呼是从两个角度描述的同一个概念。
从Spring容器的角度来看,Spring容器负责将被依赖对象赋值给调用者的成员变量,这相当于为调用者注入了它依赖的实例,这就是Spring的依赖注入。
springboot在controller中添加事务

springboot在controller中添加事务在开发过程中,碰到了一个问题,一个接口中需要插入三条数据,需要保证三条数据全部成功或者三条数据全部失败,由于使用的是MytbatisPlus,所以没有考虑在service层进行处理,通过网上找资料,找到了如下解决办法:实体类:@Data@TableName(value = "student")@KeySequence(value = "seq_student", clazz = Integer.class) public class Student implements Serializable {@TableId(value = "id", type = IdType.INPUT)private Integer id;private String nam;private String cla;}mapper层、service层、serviceImpl层都是继承了mybatisPlus 的公共类,这里就不详细介绍了,我其他博客里有这些类的写法,下面直接上controller层:@RestController@RequestMapping("/student")public class StudentController {@Autowiredprivate StudentService studentService;//添加事务第一步引入platformTransactionManager对象@Autowiredprivate PlatformTransactionManager platformTransactionManager;@RequestMapping(value = "/insert" , method = RequestMethod.POST)public Object insert(@RequestBody Map<String,Object> map){//第二步不太理解都是什么方法但是需要添加到方法中DefaultTransactionDefinition definition = new DefaultTransactionDefinition();definition.setPropagationBehavior(TransactionDefinition.PR OPAGATION_REQUIRED);TransactionStatus status = platformTransactionManager.getTransaction(definition);//第三步加入try catch语句块try{String nam = map.get("nam").toString();String cla = map.get("cla").toString();Student s = new Student();s.setNam(nam);s.setCla(cla);//第一次调用保存studentService.insert(s);s.setNam("会当凌绝顶一览众山小写代码真开心");s.setCla("故意");//第二次手动加入错误数据因为数据库中该字段最多可输入五个字符当前nam值过大会导致插入报错studentService.insert(s);//mit(status);return "添加成功";}catch (Exception e){//第二次插入报错后会被try catch捕获,捕获后执行rollback操作,第一条数据回滚platformTransactionManager.rollback(status);}return "添加失败";}}并不是太理解代码的原理,但是这样做实现了需求,找机会在深入研究。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
Spring事务原理统观spring事务,围绕着两个核心PlatformTransactionManager和TransactionStatusspring提供了几个关于事务处理的类:TransactionDefinition //事务属性定义TranscationStatus //代表了当前的事务,可以提交,回滚。
PlatformTransactionManager这个是spring提供的用于管理事务的基础接口,其下有一个实现的抽象类AbstractPlatformTransactionManager,我们使用的事务管理类例如DataSourceTransactionManager等都是这个类的子类。
一般事务定义步骤:TransactionDefinition td = new TransactionDefinition();TransactionStatus ts = transactionManager.getTransaction(td);try{ //do sthmit(ts);}catch(Exception e){transactionManager.rollback(ts);}spring提供的事务管理可以分为两类:编程式的和声明式的。
编程式的,比较灵活,但是代码量大,存在重复的代码比较多;声明式的比编程式的更灵活。
编程式主要使用transactionTemplate。
省略了部分的提交,回滚,一系列的事务对象定义,需注入事务管理对象.void add(){transactionTemplate.execute( new TransactionCallback(){pulic Object doInTransaction(TransactionStatus ts){ //do sth}}}声明式:使用TransactionProxyFactoryBean:<bean id="userManager" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"><property name="transactionManager"><ref bean="transactionManager"/></property><property name="target"><ref local="userManagerTarget"/></property><property name="transactionAttributes"><props><prop key="insert*">PROPAGATION_REQUIRED</prop><prop key="update*">PROPAGATION_REQUIRED</prop><prop key="*">PROPAGATION_REQUIRED,readOnly</prop></props></property></bean>围绕Poxy的动态代理能够自动的提交和回滚事务org.springframework.transaction.interceptor.TransactionProxyFactoryBeanPROPAGATION_REQUIRED--支持当前事务,如果当前没有事务,就新建一个事务。
这是最常见的选择。
PROPAGATION_SUPPORTS--支持当前事务,如果当前没有事务,就以非事务方式执行。
PROPAGATION_MANDATORY--支持当前事务,如果当前没有事务,就抛出异常。
PROPAGATION_REQUIRES_NEW--新建事务,如果当前存在事务,把当前事务挂起。
PROPAGATION_NOT_SUPPORTED--以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
PROPAGATION_NEVER--以非事务方式执行,如果当前存在事务,则抛出异常。
PROPAGATION_NESTED--如果当前存在事务,则在嵌套事务内执行。
如果当前没有事务,则进行与PROPAGATION_REQUIRED类似的操作。
Spring 事务管理创造性的解决了很多以前要用重量级的应用服务器才能解决的事务问题,那么其实现原理一定很深奥吧?可是如果读者仔细研究了Spring事务管理的代码以后就会发现,事务管理其实也是如此简单的事情。
这也印证了在本书开头的一句话“重剑无锋、大巧不工”,Spring并没有使用什么特殊的API,它运行的原理就是事务的原理。
下面是DataSourceTransactionManager的启动事务用的代码(经简化):protected void doBegin(Object transaction, TransactionDefinition definition){DataSourceTransactionObject txObject =(DataSourceTransactionObject) transaction;Connection con = null;try{if (txObject.getConnectionHolder() == null){Connection newCon = this.dataSource.getConnection();txObject.setConnectionHolder(new ConnectionHolder(newCon), true);}txObject.getConnectionHolder().setSynchronizedWithTransaction(true);con = txObject.getConnectionHolder().getConnection();Integer previousIsolationLevel = DataSourceUtils.prepareConnectionForTransaction(con, definition);txObject.setPreviousIsolationLevel(previousIsolationLevel);if (con.getAutoCommit()){txObject.setMustRestoreAutoCommit(true);con.setAutoCommit(false);}txObject.getConnectionHolder().setTransactionActive(true);// Bind the session holder to the thread.if (txObject.isNewConnectionHolder()){TransactionSynchronizationManager.bindResource(getDataSource(),txObject.getConnectionHolder());}}catch (SQLException ex){DataSourceUtils.releaseConnection(con, this.dataSource);throw new CannotCreateTransactionException("Could not open JDBC Connection for transaction", ex);}}本文出自:在调用一个需要事务的组件的时候,管理器首先判断当前调用(即当前线程)有没有一个事务,如果没有事务则启动一个事务,并把事务与当前线程绑定。
Spring使用TransactionSynchronizationManager的bindResource方法将当前线程与一个事务绑定,采用的方式就是ThreadLocal,这可以从TransactionSynchronizationManager类的代码看出。
public abstract class TransactionSynchronizationManager{……private static final ThreadLocal currentTransactionName = new ThreadLocal();private static final ThreadLocal currentTransactionReadOnly = new ThreadLocal();private static final ThreadLocal actualTransactionActive = new ThreadLocal(); ……}从doBegin的代码中可以看到在启动事务的时候,如果Connection是的自动提交的(也就是getAutoCommit()方法返回true)则事务管理就会失效,所以首先要调用setAutoCommit(false)方法将其改为非自动提交的。
setAutoCommit(false)这个动作在有的JDBC驱动中会非常耗时,所以最好在配置数据源的时候就将“autoCommit”属性配置为true。
首先,为什么要进行事务,接下来说说spring是怎样进行事务管理的.①Spring事务策略Spring事务策略,也就是spring事务管理的实现方式.它有一个统一的抽象是由实现下面这个接口完成的.org.springframework.transaction.PlatformTransactionManager此接口的内容如下:Public interfacePlatformTransactionManager()...{TransactionStatue getTransaction(TransactionDefinition definition) throws TransactionException;Void commit(TransactionStatus status) throws TransactionException;Void rollback(TransactionStatus status) throws TransactionException;}不管是声明式的还是编程式的事务管理都需要此抽象来完成.解释一下这个接口,这样可以更好的理解spring的事务控制的原理.getTransaction()根据类型为TransactionDefinition的参数返回一个TransactionStatus 对象.返回的TransactionStatus对象可能代表一个新的或已经存在的事务(如果在当前调用堆栈有一个符合条件的事务).如同J2EE事务上下文,一个TransactionStatus也是和执行的线程关联的.同时,在框架中还存在TransactionDefinition接口,即上边的参数类型.此接口指定了事务隔离程度、事务传播、事务超时、只读状态。