当前位置: 首页 > 后端技术 > Java

power节点的Spring框架学习笔记-王赫(4)Spring事务

时间:2023-04-01 17:55:34 Java

4.Spring事务官方下载地址Power节点spring数据视频观看地址https://www.bilibili.com/video...4.1Spring事务管理事务本来是数据库中的一个概念,在Dao层。但一般情况下,需要将事务提升到业务层,也就是Service层。这样做是为了能够利用事务的特性来管理特定的业务。在Spring中,事务管理通常可以通过以下两种方式实现:(1)使用Spring的事务注解来管理事务(2)使用AspectJ的AOP配置来管理事务4.2Spring事务管理APISpring的事务管理主要使用两个与事务相关的界面。(1)事务管理器接口(重点)事务管理器是PlatformTransactionManager接口对象。主要用于完成事务的提交和回滚,获取事务的状态信息。A.两个常用的实现类PlatformTransactionManager接口有两个常用的实现类:DataSourceTransactionManager:使用JDBC或MyBatis进行数据库操作时使用。HibernateTransactionManager:使用Hibernate持久化数据时使用。B.Spring的回滚方式(理解)Spring事务默认的回滚方式是:运行时异常和错误发生时回滚,检查(编译)异常时提交。不过对于checkedexceptions,程序员也可以手动设置回滚方式。C.查看错误和异常(理解)Throwable类是Java语言中所有错误或异常的超类。只有当对象是此类(或其子类之一)的实例时,它才能被Java虚拟机或Java的throw语句抛出。Error是程序运行过程中无法处理的错误,如OutOfMemoryError、ThreadDeath、NoSuchMethodError等,当这些错误发生时,程序无法处理(catch或throw),JVM一般会终止线程。程序编译运行时出现的另一类错误称为异常,是JVM通知程序员的一种方式。通过这种方式告知程序员已经或可能已经发生错误,需要程序员进行处理。异常分为运行时异常和检查异常。运行时异常是RuntimeException类或其子类,即只发生在运行时的异常。例如NullPointerException、ArrayIndexOutOfBoundsException、IllegalArgumentException等都是运行时异常。这些异常由JVM抛出,不需要在编译时处理(捕获或抛出)。不过,只要认真编写代码,程序足够健壮,运行时异常是可以避免的。已检查异常,也称为编译时异常,是编写代码时必须捕获或抛出的异常。如果不处理,编译将不会通过。如SQLException、ClassNotFoundException、IOException等都是checkedexceptions。除了RuntimeException及其子类之外的异常都是检查异常。当然,Exception的自定义子类,即自定义异常也是checked异常。当程序员定义异常时,只要定义没有显式声明为RuntimeException的子类,就会检查定义的异常。(2)事务定义接口事务定义接口TransactionDefinition定义了三类与事务描述相关的常量:事务隔离级别、事务传播行为、事务默认超时时间,以及它们的操作。A.定义了五个事务隔离级别常量(master)。这些常量都以ISOLATION_开头。即形状为ISOLATION_XXX。DEFAULT:使用数据库默认的事务隔离级别。MySql默认为REPEATABLE_READ;Oracle默认为READ_COMMITTED。READ_UNCOMMITTED:读取未提交。没有解决并发问题。READ_COMMITTED:读取已提交。解决脏读、不可重复读和幻读。REPEATABLE_READ:可重复读取。解决脏读、不可重复读、幻读SERIALIZABLE:序列化。没有并发问题。B.定义七个事务传播行为常量(掌握)所谓事务传播行为是指不同事务中的方法相互调用时事务在执行过程中的维护。例如A事务中的方法doSome()调用B事务中的方法doOther(),调用执行过程中事务的维护称为事务传播行为。事务传播行为被添加到方法中。事务传播行为常量均以PROPAGATION_开头,形式为PROPAGATION_XXX。PROPAGATION_REQUIREDPROPAGATION_REQUIRES_NEWPROPAGATION_SUPPORTSPROPAGATION_MANDATORYPROPAGATION_NESTEDPROPAGATION_NEVERPROPAGATION_NOT_SUPPORTEDa,PROPAGATION_REQUIRED:指定的方法必须在事务内执行。如果有当前交易,则添加到当前交易;如果没有当前事务,将创建一个新事务。这种传播行为是最常见的选择,也是Spring默认的事务传播行为。例如,将传播行为添加到doOther()方法中。如果在调用doOther()方法时doSome()方法正在事务中运行,那么doOther()方法的执行也被加入到事务中。如果在调用doOther()方法时doSome()方法没有在事务中执行,doOther()方法会创建一个事务并在其中执行。b.PROPAGATION_SUPPORTS指定的方法支持当前事务,但是如果没有当前事务,也可以以非事务的方式执行。C。PROPAGATION_REQUIRES_NEW总是创建一个新事务。如果有当前事务,则当前事务会被挂起,直到新事务执行完毕。C.定义默认事务超时常量TIMEOUT_DEFAULT定义了事务底层的默认超时时间,以及sql语句的执行时间。注意事务的超时时间有很多条件起作用,超时时间的计算点比较复杂。因此,该值一般使用默认值。4.3程序环境搭建示例:采购商品trans_sale项目本示例是实现商品的采购,模拟用户下订单,在订单表中添加销售记录,从产品表中减少库存。实现步骤:Step0:创建数据库表创建两个数据库表sale,goodssale销售表goods表goods表dataStep1:maven依赖pom.xmljunitjunit4.11testorg.springframeworkspring-context5.2.5.发布org.springframeworkspring-tx5.2.5.RELEASEorg.springframeworkspring-jdbc5.2.5.RELEASEorg.mybatismybatis3.5.1org.mybatismybatis-spring<版本>1.3.1mysqlmysql-connector-java<版本>5.1.9com.alibabadruid1.1.12插件src/main/java**/*.properties**/*.xmlfalsemaven-compiler-plugin3.11.81.8Step2:创建实体类创建实体类Sale和GoodsStep3:定义dao接口定义两个dao接口SaleDao,GoodsDaoStep4:定义dao接口对应的sql映射文件SaleDao.xmlGoodsDao.xmlStep5:定义异常类定义服务层可能抛出的异常类NotEnoughExceptionStep6:定义Service接口定义Service接口BuyGoodsServiceStep7:定义服务的实现类定义服务层接口BuyGoodsServiceImpl的实现类1)类定义2)Dao属性3)Buy方法Step8:修改Spring配置文件内容,声明Mybatis对象声明业务层对象Step9:定义测试类现在定义测试类MyTest现在可以在没有事务代理的情况下运行。4.4使用Spring的事务注解管理事务(master)通过@Transactional注解,可以将事务编织到相应的公共方法中,实现事务管理。@Transactional的所有可选属性如下:propagation:用于设置事务传播属性。属性类型为Propagation枚举,默认值为Propagation.REQUIRED。isolation:用于设置事务的隔离级别。属性类型为Isolation枚举,默认值为Isolation.DEFAULT。readOnly:用于设置方法对数据库的操作是否只读。此属性为布尔值,默认值为false。timeout:用于设置本次操作连接数据库的超时时间。单位是秒,类型是int,默认值为-1,即没有时间限制。rollbackFor:指定需要回滚的异常类。类型为Class[],默认值为空数组。当然,如果只有一个异常类,就不需要用数组了。rollbackForClassName:指定需要回滚的异常类的名称。类型为String[],默认值为空数组。当然,如果只有一个异常类,就不需要用数组了。noRollbackFor:指定不需要回滚的异常类。类型为Class[],默认值为空数组。当然,如果只有一个异常类,就不需要用数组了。noRollbackForClassName:指定不需要回滚的异常类的名称。类型为String[],默认值为空数组。当然,如果只有一个异常类,就不需要用数组了。需要注意的是,@Transactional如果用在方法上,只能用在public方法上。对于其他非public的方法,如果加上注解@Transactional,Spring虽然不会报错,但是也不会把指定的事务编织到方法中。因为Spring会忽略所有非公共方法上的@Transaction注解。如果@Transaction注解在类上,则意味着类上的所有方法在执行时都会被编织到事务中。实现注解的事务步骤:复制trans_sale项目,新建项目trans_sale_annotation1.声明事务管理器2.开启注解驱动的transaction-manager:事务管理器bean的id3.添加事务属性业务层的公共方法4.5使用AspectJ的AOP配置管理事务(Grasp)使用XML配置事务代理的缺点是每个目标类都需要配置事务代理。当目标类很多时,配置文件会变得非常臃肿。使用XML配置顾问方法为每个匹配切入点表达式的类自动生成事务代理。它的使用非常简单,只需要删除之前代码中事务代理的配置,替换成如下内容即可。Step1:复制项目复制trans_sale项目,重命名为trans_sal_aspectj。在此基础上修改。Step2:Maven依赖pom.xml和新增aspectj依赖坐标org.springframeworkspring-aspects5.2.5.RELEASEStep3:在容器中添加事务管理器Step4:配置事务通知,设置事务通知的相关属性。用于指定如何将事务编织到哪些方法中。比如buy方法上应用的事务需求是required,当buy方法出现异常时需要回滚业务。Step5:配置增强器指定将配置的交易通知编织给谁。Step6:修改测试类测试类中要从容器中获取的对象就是目标对象。