您的位置:首页 > 财经 > 金融 > 新品手机上市_自建网站平台有哪些功能_竞价网_搜索引擎优化中的步骤包括

新品手机上市_自建网站平台有哪些功能_竞价网_搜索引擎优化中的步骤包括

2024/12/23 1:16:35 来源:https://blog.csdn.net/2201_75490194/article/details/144609598  浏览:    关键词:新品手机上市_自建网站平台有哪些功能_竞价网_搜索引擎优化中的步骤包括
新品手机上市_自建网站平台有哪些功能_竞价网_搜索引擎优化中的步骤包括

一、什么是事务管理

事务是一个最小的不可再分的工作单元。 一个事务对应一套完整的业务操作。事务管理是指这些操作要么全部成功执行,要么全部回滚,从而保证数据的一致性和完整性。比如银行转账,需要保证转出和转入是一个原子操作。Spring提供了声明式编程式两种事务管理方式。

二、Spring编程式事务管理

Spring框架提供了专门用于事务管理的API。要使用Spring实现事务管理需要引入spring-tx依赖

首先在pom.xml文件中引入spring-tx依赖

<!--spring-tx依赖-->
<dependency><groupId>org.springframework</groupId><artifactId>spring-tx</artifactId><version>6.1.8</version>
</dependency>

其中有三个核心接口

  • PlatformTransactionManager.class
  • TransactionDefinitionn.class
  • TransactionStatus.class

PlatformTransactionManager接口

PlatformTransactionManager 接口是 Spring 提供的平台事务管理器,主要用于管理事务。该接口中提供了三个事务操作的方法。

  • TransactionStatus getTransaction(TransactionDefinition definition);
    用于获取事务以及状态信息
  • void commit(TransactionStatus status);
    用于提交事务
  • void rollback(TransactionStatus status);
    用于回滚事务

PlatformTransactionManager 接口只是代表事务管理的接口,并不知道底层是如何管理事务的,具体如何管理事务则由它的实现类来完成。该接口常见的几个实现类如下:
在这里插入图片描述

TransactionDefinition接口

TransactionDefinition 接口是事务定义(描述)的对象,该对象中定义了事务基本属性,并提供了获取事务基本属性的方法,具体如下:

  • String getName( ); ---------- 获取事务对象名称
  • int getIsolationLevel( ); ---------- 获取事务的隔离级别
  • int getPropagationBehavior( ); ---------- 获取事务的传播行为
  • int getTimeout( ); ---------- 获取事务的超时时间
  • boolean isReadOnly( ); ---------- 获取事务是否只读
事务的传播行为

当事务方法被另一个事务方法调用时,必须指定事务应该如何传播。Spring定义了七种传播行为。
在这里插入图片描述

事务的隔离级别

定义了一个事务可能受其他并发事务的影响程度。多个事务并发运行,经常会操作相同的数据来完成各自的任务,可能会出现脏读,不可重复读和幻读的问题。隔离级别有四种。
在这里插入图片描述

  • 脏读:一个事务读取到了另一个事务未提交的数据
  • 不可重复读:同一个事务内多次读取同一数据,但前后两次读取的结果不一致。由其他事务的更新操作造成。
  • 幻读:同一个事务内多次查询记录数量,但前后两次查询的结果不一致。由其他事务的插入或删除操作造成。
是否只读

如果一个方法内都是对数据库的select操作,那么可以设置方法事务为只读,数据库也会对该事务进行特定的优化。只读事务内不能有insert、update、delete的操作。

事务超时

事务可能涉及对后端数据库的锁定,所以长时间的事务运行会不必要的占用数据库资源,设置事务超时时间可以及时释放资源

默认实现类DefaultTransactionDefinition

DefaultTransactionDefinition 是 Spring 提供的 TransactionDefinition 接口的默认实现类

@SuppressWarnings("serial")
public class DefaultTransactionDefinition implements TransactionDefinition, Serializable {private int propagationBehavior = PROPAGATION_REQUIRED; // 必须使用事务private int isolationLevel = ISOLATION_DEFAULT; //数据库默认隔离级别(可重复读)private int timeout = TIMEOUT_DEFAULT; // 永不超时private boolean readOnly = false; // 不是只读// 其他省略
}

TransactionStatus接口

TransactionStatus 接口是事务的状态,它描述了某一时间点上事务的状态信息。该接口中包含6个方法,具体如下:

  • void flush(); ---------- 刷新事务
  • boolean hasSavepoint(); ---------- 获取是否存在保存点
  • boolean isCompleted(); ---------- 获取事务是否完成
  • boolean isNewTransaction(); ---------- 获取是否为新事务
  • boolean isRollbackOnly(); ---------- 获取事务是否回滚
  • void setRollbackOnly(); ---------- 设置事务回滚

1.在配置文件中配置事务管理器组件

spring-mybatis.xml

	 <!-- 配置事务管理器 --><bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="dataSource"/></bean>

2.在业务逻辑组件方法中使用事务管理器组件实现事务管理功能

// 以添加学生信息为例,需要同时往学生表和学生证表插入数据
@Service
public class StudentService {@Autowiredprivate StudentMapper studentMapper;@Autowiredprivate StudentCardMapper studentCardMapper;@Autowiredprivate PlatformTransactionManager transactionManager;public void addStudent(StudentParam param) {// 1.定义事务属性DefaultTransactionDefinition def = new DefaultTransactionDefinition();// 可以设置事务的隔离级别、传播行为等def.setIsolationLevel(TransactionDefinition.ISOLATION_READ_COMMITTED);def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);// 2.获取事务状态TransactionStatus status = transactionManager.getTransaction(def);try {// 3.执行业务逻辑Student student = BeanUtil.copyProperties(param, Student.class);studentMapper.insertStudent(student);StudentCard card = BeanUtil.copyProperties(param, StudentCard.class);card.setStuId(student.getStuId());studentCardMapper.insertStudentCard(card);// 4.提交事务transactionManager.commit(status);} catch (Exception e) {// 5.异常回滚transactionManager.rollback(status);throw new RuntimeException("添加学生信息失败", e);}}
}

三、Spring声明式事务管理

Spring声明式事务管理最大的优点在于开发者无需通过编程的方式来管理事务,只需在配置文件中进行相关的事务规则声明,就可以将事务应用到业务逻辑中。在实际开发中,通常都推荐使用声明式事务管理。
Spring声明式事务管理通过AOP技术实现的事务管理,主要思想是将事务作为一个“切面”代码单独编写,然后通过AOP技术将事务管理的“切面”植入到业务目标类方法中。
Spring的声明式事务管理可以通过两种方式来实现

  • 基于XML方式
  • 基于注解方式

首先在pom.xml文件中引入AOP切面依赖

 <!-- AOP  --><dependency><groupId>org.springframework</groupId><artifactId>spring-aspects</artifactId><version>6.1.8</version></dependency>

XML配置方式

1. 在Spring配置文件中配置事务管理器

spring-mybatis.xml

<!-- 配置事务管理器 -->
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="dataSource"/>
</bean>

2.使用<tx:advice>标签配置事务规则

spring-mybatis.xml

<!-- 配置事务通知 -->
<!-- id表示唯一标识  transaction-manager表示关联的事务管理器-->
<tx:advice id="txAdvice" transaction-manager="txManager"><tx:attributes><!-- 定义哪些方法需要进行事务处理,*表示任意字符,比如find*表示以find开头的方法 --><!-- 查询方法:只读事务 --><tx:method name="get*" read-only="true"/><tx:method name="find*" read-only="true"/><tx:method name="select*" read-only="true"/><!-- 增删改方法:读写事务 --><tx:method name="add*" propagation="REQUIRED" isolation="READ_COMMITTED"/><tx:method name="save*" propagation="REQUIRED" isolation="READ_COMMITTED"/><tx:method name="update*" propagation="REQUIRED" isolation="READ_COMMITTED"/><tx:method name="delete*" propagation="REQUIRED" isolation="READ_COMMITTED"/></tx:attributes>
</tx:advice>

attributes(属性)

  • name :指定对哪些方法起作用
  • propagation :指定事务的传播行为
  • isolation :指定事务的隔离级别
  • read-only :指定事务是否只读
  • timeout: 指定事务超时的时间
  • rollback-for :指定异常回滚
  • no-rollback-for :指定异常不回滚

3. 使用<aop:config>配置事务切面,通过<aop:pointcut>配置切点,通过<aop:advisor>标签配置切点执行的事务规则

spring-mybatis.xml

<!-- 配置事务切面 -->
<!-- 定义切面 -->
<aop:config><!-- 定义切点 --><aop:pointcut id="txPointcut" expression="execution(* com.cg.service.*.*(..))"/><!-- 在指定的切点上应用事务规则 --><!-- advice-ref关联事务规则 pointcut-ref关联切点 --><aop:advisor advice-ref="txAdvice" pointcut-ref="txPointcut"/>
</aop:config>

注解方式

基于注解方式实现是通过使用@Transactional注解来实现方法的事务管理功能

1. 在Spring配置文件中配置事务管理器

spring-mybatis.xml

<!-- 配置事务管理器 -->
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="dataSource"/>
</bean>

2. 在Spring容器中注册事务注解驱动

<!--注册事务注解驱动--><tx:annotation-driven transaction-manager="txManager"/>

3.在需要事务管理的类或方法上使用@Transactional注解

使用@Transactional注解时,可以通过参数配置具体事务属性
在这里插入图片描述

四、事务传播行为详解

通过实际案例理解事务传播行为:

REQUIRED(默认)

如果当前没有事务,就创建一个新事务;如果已经存在一个事务,就加入到这个事务中。

@Service
public class AService {@Autowired private BService bService;@Transactional(propagation = Propagation.REQUIRED)public void methodA() {// methodA开启事务1insert("A");// methodB加入事务1bService.methodB();  // 如果这里抛异常,整个事务都会回滚}
}@Service
public class BService {@Transactional(propagation = Propagation.REQUIRED)public void methodB() {// 加入methodA的事务1insert("B");throw new RuntimeException();  // 异常导致整个事务1回滚}
}

REQUIRES_NEW

总是会开启一个新的事务。如果一个事务已经存在,则将这个存在的事务挂起。

@Service
public class AService {@Autowiredprivate BService bService;@Transactional(propagation = Propagation.REQUIRED)public void methodA() {// methodA开启事务1insert("A");  // 这条数据会插入成功try {// methodB开启新事务2,事务1被挂起bService.methodB();} catch (Exception e) {// methodB事务2回滚,事务1不受影响}}
}@Service
public class BService {@Transactional(propagation = Propagation.REQUIRES_NEW)public void methodB() {insert("B1");  // 这条数据会回滚int i = 1/0;   // 抛出异常insert("B2");  // 不会执行}
}

NESTED

如果当前存在事务,则在嵌套事务内执行;如果当前没有事务,则创建一个新事务。

@Service
public class AService {@Transactional(propagation = Propagation.REQUIRED)public void methodA() {// 外部事务insert("A");  // 这条数据会保存try {// 内部嵌套事务methodB();} catch (Exception e) {// 内部事务回滚,外部事务可以正常提交}}@Transactional(propagation = Propagation.NESTED)public void methodB() {insert("B");  // 这条数据会回滚throw new RuntimeException();}
}

SUPPORTS

如果当前有事务就加入,没有就以非事务方式执行。

@Service
public class AService {    @Transactional(propagation = Propagation.REQUIRED)public void methodA() {// 有事务methodB();  // methodB会加入当前事务}public void methodC() {// 无事务调用methodB();  // methodB以非事务方式执行}
}@Service
public class BService {@Transactional(propagation = Propagation.SUPPORTS)public void methodB() {// 有事务就用事务,没有就不用insert("B");}
}

NOT_SUPPORTED

总是以非事务方式执行,如果当前有事务则挂起。

@Service
publicclass AService {@Transactional(propagation = Propagation.REQUIRED)public void methodA() {insert("A");  // 在事务中执行methodB();    // 挂起当前事务,以非事务方式执行}@Transactional(propagation = Propagation.NOT_SUPPORTED)public void methodB() {// 总是以非事务方式执行insert("B");  // 即使外部有事务也以非事务方式执行}
}

MANDATORY

必须在一个已有事务中执行,否则抛异常。

@Service
public class AService {@Transactional(propagation = Propagation.REQUIRED)public void methodA() {methodB();  // 正常执行,因为当前有事务}public void methodC() {methodB();  // 抛出异常,因为没有事务}
}@Service
public class BService {@Transactional(propagation = Propagation.MANDATORY)public void methodB() {// 必须在一个已有事务中执行insert("B");}
}

NEVER

总是以非事务方式执行,如果当前有事务就抛异常

@Service
public class Aervice {@Transactional(propagation = Propagation.REQUIRED)public void methodA() {methodB();  // 抛出异常,因为当前有事务}public void methodC() {methodB();  // 正常执行,因为没有事务}@Service
public class BService {@Transactional(propagation = Propagation.NEVER)public void methodB() {// 必须在非事务环境下执行insert("B");}
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com