网站要怎么运营,两学一做纪实评价系统网站,千年之恋网页设计代码,广州网站建设找哪家补充#xff1a;事务的传播行为是啥
事务的传播行为#xff1a;指的是#xff0c;当一个事务方法被另一个事务方法调用时#xff0c;这个被调用的事务方法应该如何进行#xff0c; 简单来说#xff0c;它决定了事务方法是在调用者的事务中运行#xff0c;还是为自己开启…补充事务的传播行为是啥
事务的传播行为指的是当一个事务方法被另一个事务方法调用时这个被调用的事务方法应该如何进行 简单来说它决定了事务方法是在调用者的事务中运行还是为自己开启一个新的事务运行。
在Spring框架中 事务的传播行为是通过Transactional注解的propagation属性来配置的 Spring定义了七种类型的事务传播行为每种行为都有其特定的用途和场景。其中最常见的包括
PROPAGATION_REQUIRED默认值如果父方法有事务我们就加入到父方法的事务最终是同一个事务 如果父方法没有事务就新建自己独立的事务PROPAGATION_REQUIRES_NEW创建一个新的事务如果当前存在事务把当前事务挂起。PROPAGATION_NESTED如果当前存在事务则在嵌套事务内执行。如果当前没有事务则执行REQUIRED行为。PROPAGATION_NOT_SUPPORTED以非事务方式执行操作如果当前存在事务就把当前事务挂起。PROPAGATION_NEVER以非事务方式执行如果当前存在事务则抛出异常。
这些传播行为提供了灵活的事务管理策略可以根据具体的应用场景和需求来选择合适的传播行为。通过合理配置事务的传播行为可以确保数据的一致性和完整性同时提高系统的性能和可靠性。
Spring事务管理器
1、Spring声明式事务对应依赖 spring-tx包含声明式事务实现的基本规范事务管理器规范接口 和 事务增强等等spring-jdbc包含DataSource方式事务管理器实现类 DataSourceTransactionManagerspring-orm包含其他持久层框架的事务管理器实现类如Hibernate/Jpa等2、spring声明式事务对应事务管理器接口 TransactionManager 顶层接口||PlatformTransactionManager 接口| || |DataSourceTransactionManager实现类 HibernateTransactionManager实现类Spring框架中TransactionManager是一个顶层接口用于定义事务管理行为的顶层接口提供了开始事务、提交事务、回滚事务等方法的定义。作用定义了事务管理的标准行为可以有不同的实现类来实现具体的事务管理逻辑。PlatformTransactionManager是Spring框架中的事务管理平台接口定义了对事务进行管理的方法。作用作为事务管理的核心接口定义了事务的开始、提交、回滚等操作具体的事务管理器实现类需要实现这些方法。DataSourceTransactionManager是Spring框架中用于基于数据源的事务管理的实现类用于管理JDBC事务。作用通过数据源管理事务可以在Spring应用中使用JDBC进行数据库访问并通过该事务管理器实现事务管理。HibernateTransactionManager是Spring框架中用于与Hibernate集成的事务管理器实现类用于管理Hibernate事务。作用通过与Hibernate集成可以在Spring应用中使用Hibernate进行ORM操作并通过该事务管理器实现事务管理。
我们现在使用的事务管理器是org.springframework.jdbc.datasource.DataSourceTransactionManager
将来整合JDBC方式、JdbcTemplate方式、Mybatis方式的事务实现。
3、DataSourceTransactionManager类中主要方法 doBegin()开启事务doSuspend()挂起事务doResume()恢复挂起的事务doCommit()提交事务doRollback()回滚事务举个例子
1、数据库的配置文件src/main/resources/jdbc.properties atguigu.urljdbc:mysql:///my_studyatguigu.drivercom.mysql.cj.jdbc.Driveratguigu.usernamerootatguigu.passwordroot2、配置类src/main/java/com.atguigu.config/JavaConfig.java
package com.atguigu.config;import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.*;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.TransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;import javax.sql.DataSource;Configuration 1、说明这是个配置类
ComponentScan(com.atguigu) 2、包扫描
PropertySource(classpath:jdbc.properties) 3、引入配置文件
EnableAspectJAutoProxy 开启aspectj注解的支持
EnableTransactionManagement 开启事务注解的支持
public class JavaConfig {这里读取 src/main/resources/jdbc.properties文件的数据库相关配置Value(${atguigu.driver})private String driver;Value(${atguigu.url})private String url;Value(${atguigu.username})private String username;Value(${atguigu.password})private String password;4、druid连接池实例化DruidDataSource实现了DataSource接口所以这里用 public DataSource dataSource()Beanpublic DataSource dataSource() {DruidDataSource dataSource new DruidDataSource();dataSource.setDriverClassName(driver);dataSource.setUrl(url);dataSource.setUsername(username);dataSource.setPassword(password);return dataSource;}5、jdbcTemplateBeanpublic JdbcTemplate jdbcTemplate(DataSource dataSource){JdbcTemplate jdbcTemplate new JdbcTemplate();jdbcTemplate.setDataSource(dataSource);return jdbcTemplate;}Beanpublic TransactionManager transactionManager(DataSource dataSource){* 内部需要进行事务的操作基于的连接池DataSourceTransactionManager dataSourceTransactionManager new DataSourceTransactionManager();* 需要连接池对象dataSourceTransactionManager.setDataSource(dataSource);return dataSourceTransactionManager;}
}
3、dao层src/main/java/com.atguigu.dao/StudentDao.java
package com.atguigu.dao;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;Repository
public class StudentDao {Autowiredprivate JdbcTemplate jdbcTemplate;public void updateNameById(String name, Integer id){String sql update my_user set name ? where id ?;int rows jdbcTemplate.update(sql, name, id);}public void updatePloneById(String plone, Integer id){String sql update my_user set plone ? where id ?;int rows jdbcTemplate.update(sql, plone, id);}
}
4、service层src/main/java/com.atguigu.service/StudentService.java package com.atguigu.service;import com.atguigu.dao.StudentDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;import java.io.FileInputStream;
import java.io.FileNotFoundException;Service
public class StudentService {Autowiredprivate StudentDao studentDao;* 怎样添加事务呢使用 Transactional注解 即可* 这个Transactional注解在哪加呢方式1、加到某个方法上那么这个方法就有事务了方式2、加到某个类上那么这个类的所有方法就都有事务了* Transactional注解的属性1、只读模式只读模式可以提升查询事务的效率推荐事务中只有查询代码时使用只读模式默认情况下源码boolean readOnly() default false解释一般情况下都是直接把 Transactional注解 加到类上则这个类的所有方法就都有事务了但是你可以在查询方法上再加一次 Transactional注解并且设置只读模式提高效率2、超时时间事务在执行过程中可能会由于某些问题导致卡住从而长时间占用数据库资源而长时间占用数据库资源大概率是因为程序出现了问题(可能是Java程序、Mysql数据库、网络连接等问题)此时这个很可能出现问题的程序就应该被回滚撤销他已做的操作事务结束把资源让出来让其他程序可以正常执行总之就是超时回滚、释放资源默认永不超时值是-1设置 timeout 秒数超时后就会回滚事务和释放异常超时的异常是TransactionTimedOutException如果类上设置了 Transactional注解 和 这个timeout属性并且方法上也设置了 Transactional注解但是没有设置timeout属性那么此时方法上的timeout值是 默认值 -1 哦3、指定异常回滚 和 指定异常不回滚默认情况下发生运行时异常才会回滚我们可以指定Exception异常来控制所有异常都会滚rollbackFor Exception.class意思是所有的异常都回滚noRollbackFor FileNotFoundException.class意思是指定FileNotFoundException异常不回滚Transactional(timeout 3, rollbackFor Exception.class, noRollbackFor FileNotFoundException.class)public void changeInfo() throws FileNotFoundException {studentDao.updatePloneById(1390002, 1);加这句代码是为了测试事务是否加上了int i 1/0; 这句代码本身是会报错的因为有事务的话即使 int i 1/0; 这句代码上面的代码没有错但是 int i 1/0; 报错了会造成回滚所以整个方法里的代码都不会生效。但是如果没有事务的话int i 1/0; 这句代码上面正确的代码会执行生效的// int i 1/0;// try {
// Thread.sleep(5000); // 等5秒为了测试 timeout这个属性
// } catch (InterruptedException e) {
// throw new RuntimeException(e);
// }测试异常回滚new FileInputStream(xxx);System.out.println(----------------------------);studentDao.updateNameById(springtx-改名, 2);}事务传播行为声明两个独立修改数据库的事务业务方法propagation Propagation.REQUIRED意思是如果父方法有事务我们就加入到父方法的事务最终是同一个事务如果父方法没有事务就新建自己独立的事务propagation Propagation.REQUIRES_NEW意思是不管父方法是否有事务我都是独立的事务Transactional(propagation Propagation.REQUIRES_NEW)public void changePlone(){studentDao.updatePloneById(1390004, 1);}Transactional(propagation Propagation.REQUIRES_NEW)public void changeName(){studentDao.updateNameById(spring-tx-嘎嘎, 2);int i 1 / 0; // 报错}}
5、最后写一个测试类src/test/com.atguigu.test/SpringTest.java
package com.atguigu.test;import com.atguigu.config.JavaConfig;
import com.atguigu.service.StudentService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;import java.io.FileNotFoundException;SpringJUnitConfig(JavaConfig.class)
public class SpringTxTest {Autowiredprivate StudentService studentService;Testpublic void test() throws FileNotFoundException {studentService.changeInfo();}Testpublic void test1(){studentService.changePlone(); 会改变数据库的内容studentService.changeName(); 不会改变数据库的内容因为报错导致事务回滚了}TestTransactional 即使父方法这里加上Transactional但是下面着2个方法的propagation Propagation.REQUIRES_NEW所以结果如下public void test2(){studentService.changePlone(); 会改变数据库的内容studentService.changeName(); 不会改变数据库的内容因为报错导致事务回滚了}}