asp源代码网站河南网站推广优化公司
asp源代码网站,河南网站推广优化公司,推销网站话术,国外网站上不去 dns文章目录目录结构怎样添加事务Spring事务管理器spring声明式事务#xff08;事务管理器接口#xff09;DataSourceTM 类中主要方法例子dao层service层#xff08;事务的使用步骤#xff09;配置类测试方法原来的解释事务的传播行为service层#xff1a;src/main/java/com.…文章目录目录结构怎样添加事务Spring事务管理器spring声明式事务事务管理器接口DataSourceTM 类中主要方法例子dao层service层事务的使用步骤配置类测试方法原来的解释事务的传播行为service层src/main/java/com.atguigu.service/StudentService.javaTopService.java声明一个整合业务方法添加传播行为测试解释目录结构怎样添加事务添加事务的步骤基于注解的声明式事务1、选择对应的 事务管理器实现 加入到ioc容器 spring的声明式事务给我们提供了多个管理器实现 你需要哪种具体是哪种根据你的数据库框架选择就行了就把它加入到ioc容器即可。 比如 如果用的mybatis或者jdbcTemplate就选择DataSourceTransactionManager如果用的 hibernate就选择HibernateTM还有其他的...2、然后就按下面的步骤 怎样添加事务呢 步骤1配置类添加EnableTransactionManagement开启事务注解的支持 并且声明 DataSourceTM BeanBeanpublicTransactionManagertransactionManager(DruidDataSourcedataSource){// 因为DataSourceTM 内部需要事务的操作且事务的操作基于 druid连接池DataSourceTransactionManagerdataSourceTMnewDataSourceTransactionManager(dataSource);// 所以需要给 DataSourceTM 设置上 DruidDataSource dataSourcedataSourceTM.setDataSource(dataSource);returndataSourceTM;}步骤2 就可以使用Transactional注解了 在哪里使用这个注解呢 方式1、加到某个方法上那么这个方法就有事务了 方式2、加到某个类上那么这个类的所有方法就都有事务了Spring事务管理器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方式的事务实现。DataSourceTM 类中主要方法doBegin() 开启事务doSuspend()挂起事务doResume()恢复挂起的事务doCommit()提交事务doRollback()回滚事务例子dao层packagecom.english.dao;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.jdbc.core.JdbcTemplate;importorg.springframework.stereotype.Repository;RepositorypublicclassStudentDao{AutowiredprivateJdbcTemplatejdbcTemplate;publicvoidupdateNameById(Stringname,Integerid){Stringsqlupdate students set name ? where id ? ;;introwsjdbcTemplate.update(sql,name,id);}publicvoidupdateAgeById(Integerage,Integerid){Stringsqlupdate students set age ? where id ? ;;jdbcTemplate.update(sql,age,id);}}service层事务的使用步骤packagecom.english.service;importcom.english.dao.StudentDao;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.stereotype.Service;importorg.springframework.transaction.annotation.Isolation;importorg.springframework.transaction.annotation.Transactional;importjava.io.FileInputStream;importjava.io.FileNotFoundException;/** * 添加事务的步骤基于注解的声明式事务 * 1、选择对应的 事务管理器实现 加入到ioc容器 * spring的声明式事务给我们提供了多个管理器实现 * 你需要哪种具体是哪种根据你的数据库框架选择就行了就把它加入到ioc容器即可。 * 比如 * 如果用的 mybatis 或者 jdbcTemplate就选择 DataSourceTransactionManager * 如果用的 hibernate就选择 HibernateTM * 还有其他的 ... * 2、然后就按下面的步骤 * * 怎样添加事务呢 * 首先 * 配置类添加 EnableTransactionManagement 开启事务注解的支持 * 并且声明 DataSourceTM Bean * Bean * public TransactionManager transactionManager(DruidDataSource dataSource){ * // 因为DataSourceTM 内部需要事务的操作且事务的操作基于 druid连接池 * DataSourceTransactionManager dataSourceTransactionManager new DataSourceTransactionManager(dataSource); * // 所以需要给 DataSourceTM 设置上 DruidDataSource dataSource * dataSourceTransactionManager.setDataSource(dataSource); * return dataSourceTransactionManager; * } * 然后 * 就可以使用 Transactional注解了 * 在哪里使用这个注解呢 * 方式1、加到某个方法上那么这个方法就有事务了 * 方式2、加到某个类上那么这个类的所有方法就都有事务了 * * 事务属性只读模式 * 为什么会有只读模式 * 一般情况下我们都是直接把 Transactional 加到类上 * 这时这个类的所有方法就都有事务了 * 但是这个类的某个方法queryAAA只是一个简单的查询功能 * 这时候就可以使用 只读模式 了 * 在查询方法queryAAA 上使用 Transactional(readOnlytrue) 设置只读模式 * * 事务属性超时时间 * 事务在执行过程中可能会由于某些问题导致卡住从而长时间占用数据库资源 * 而长时间占用数据库资源大概率是因为程序出现了问题(可能是Java程序、Mysql数据库、网络连接等问题) * 此时这个很可能出现问题的程序就应该被回滚撤销他已做的操作事务结束把资源让出来让其他程序可以正常执行 * 总之就是超时回滚、释放资源 * * 超时时间默认永不超时值是-1 * 设置 timeout 秒数超时后就会回滚事务和释放异常 * * 超时的异常是TransactionTimedOutException * * 如果类上设置了 Transactional 和 timeout属性 * 并且方法上也设置了 Transactional但是没有设置 timeout属性 * 此时方法上的timeout值是 默认值 -1 哦 * * 事务的异常指定 * 默认情况下发生运行时异常事务才会回滚 * 但是你可以指定 Exception异常控制所有异常事务都会回滚 * rollbackFor Exception.class意思是所有的异常都回滚 * noRollbackFor FileNotFoundException.class意思是指定 FileNotFoundException 异常不回滚 * * 例子Transactional(timeout 3, rollbackFor Exception.class, noRollbackFor FileNotFoundException.class * * 看一看 testYiChang() 方法的例子 * * 事务的隔离级别isolation 属性 * 数据库事务的隔离级别是指在多个事务并发执行时数据库系统为了保证数据一致性所遵循的规定。 * 常见的隔离级别包括 * 1. 读未提交Read Uncommitted事务可以读取未被提交的数据容易产生脏读、不可重复读和幻读等问题。实现简单但不太安全一般不用。 * 2. 读已提交Read Committed事务只能读取已经提交的数据可以避免脏读问题但可能引发不可重复读和幻读。 * 3. 可重复读Repeatable Read在一个事务中相同的查询将返回相同的结果集不管其他事务对数据做了什么修改。可以避免脏读和不可重复读但仍有幻读的问题。 * 4. 串行化Serializable最高的隔离级别完全禁止了并发只允许一个事务执行完毕之后才能执行另一个事务。可以避免以上所有问题但效率较低不适用于高并发场景。 * * 不同的隔离级别适用于不同的场景需要根据实际业务需求进行选择和调整。 * * 推挤使用第2个读已提交Read Committed级别 * * 使用方法 * Transactional(rollbackFor Exception.class, isolation Isolation.REPEATABLE_READ) */ServicepublicclassStudentService{AutowiredprivateStudentDaostudentDao;// 这个方法被 Transactional 修饰了此方法就有事务了TransactionalpublicvoidchangeInfo(){studentDao.updateAgeById(66,1);// 这里添加个报错的代码// 如果有事务这里报错后会回滚上面那句代码不会生效的// 如果没有事务的话上面那句代码会生效的inti1/0;System.out.println(---------------------);studentDao.updateNameById(tx-test-1,1);}// 这个方法用来测试事务的异常指定// Transactional(rollbackFor Exception.class, noRollbackFor FileNotFoundException.class)Transactional(rollbackForException.class,isolationIsolation.REPEATABLE_READ)publicvoidtestYiChang()throwsFileNotFoundException{studentDao.updateAgeById(56,1);// 这行代码会报错java.io.FileNotFoundException: xxx (系统找不到指定的文件。)// 如果这里不指定 rollbackFor Exception.class事务是不会回滚的// 事务回不回滚看上面那行代码生没生效即可newFileInputStream(xxx);studentDao.updateNameById(tx-test-2,1);}}配置类packagecom.english.config;importcom.alibaba.druid.pool.DruidDataSource;importorg.springframework.beans.factory.annotation.Value;importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.ComponentScan;importorg.springframework.context.annotation.Configuration;importorg.springframework.context.annotation.PropertySource;importorg.springframework.jdbc.core.JdbcTemplate;importorg.springframework.jdbc.datasource.DataSourceTransactionManager;importorg.springframework.transaction.TransactionManager;importorg.springframework.transaction.annotation.EnableTransactionManagement;ConfigurationComponentScan(com.english)PropertySource(classpath:jdbc.properties)EnableTransactionManagement// 开启事务注解的支持publicclassJavaConfig{Value(${atguigu.driver})privateStringdriverClassName;Value(${atguitu.url})privateStringurl;Value(${atguigu.username})privateStringusername;Value(${atguigu.password})privateStringpassword;// druid 连接池BeanpublicDruidDataSourcedataSource(){DruidDataSourcedataSourcenewDruidDataSource();dataSource.setUrl(url);dataSource.setUsername(username);dataSource.setPassword(password);dataSource.setDriverClassName(driverClassName);returndataSource;}BeanpublicJdbcTemplatejdbcTemplate(DruidDataSourcedataSource){JdbcTemplatejdbcTemplatenewJdbcTemplate();jdbcTemplate.setDataSource(dataSource);returnjdbcTemplate;}BeanpublicTransactionManagertransactionManager(DruidDataSourcedataSource){// 因为DataSourceTM 内部需要事务的操作且事务的操作基于 druid连接池DataSourceTransactionManagerdataSourceTransactionManagernewDataSourceTransactionManager(dataSource);// 所以需要给 DataSourceTM 设置上 DruidDataSource dataSourcedataSourceTransactionManager.setDataSource(dataSource);returndataSourceTransactionManager;}}测试方法importcom.english.config.JavaConfig;importcom.english.service.StudentService;importorg.junit.jupiter.api.Test;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.test.context.junit.jupiter.SpringJUnitConfig;importjava.io.FileNotFoundException;SpringJUnitConfig(JavaConfig.class)publicclassTxTest{AutowiredprivateStudentServicestudentService;Testpublicvoidtest()throwsFileNotFoundException{// studentService.changeInfo();// 这个方法用来测试事物的异常指定studentService.testYiChang();}}原来的解释事务的传播行为事务的传播行为当一个事务方法被另一个事务方法调用时这个被调用的事务方法应该如何进行简单来说它决定了事务方法是在调用者的事务中运行还是为自己开启一个新的事务运行。在Spring框架中事务的传播行为是通过Transactional注解的propagation属性配置的Spring定义了七种类型的事务传播行为每种行为都有其特定的用途和场景。其中最常见的包括PROPAGATION_REQUIRED默认值如果父方法有事务我们就加入到父方法的事务最终是同一个事务如果父方法没有事务就新建自己独立的事务PROPAGATION_REQUIRES_NEW创建一个新的事务如果当前存在事务把当前事务挂起。PROPAGATION_NESTED如果当前存在事务则在嵌套事务内执行。如果当前没有事务则执行REQUIRED行为。PROPAGATION_NOT_SUPPORTED以非事务方式执行操作如果当前存在事务就把当前事务挂起。PROPAGATION_NEVER以非事务方式执行如果当前存在事务则抛出异常。这些传播行为提供了灵活的事务管理策略可以根据具体的应用场景和需求来选择合适的传播行为。通过合理配置事务的传播行为可以确保数据的一致性和完整性同时提高系统的性能和可靠性。service层src/main/java/com.atguigu.service/StudentService.javapackagecom.atguigu.service;importcom.atguigu.dao.StudentDao;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.stereotype.Service;importorg.springframework.transaction.annotation.Transactional;importjava.io.FileInputStream;importjava.io.FileNotFoundException;ServicepublicclassStudentService{AutowiredprivateStudentDaostudentDao;*怎样添加事务呢 使用Transactional注解 即可*这个Transactional注解在哪加呢 方式1、加到某个方法上那么这个方法就有事务了 方式2、加到某个类上那么这个类的所有方法就都有事务了*Transactional注解的属性1、只读模式 只读模式可以提升查询事务的效率推荐事务中只有查询代码时使用只读模式 默认情况下源码booleanreadOnly()defaultfalse解释一般情况下都是直接把Transactional注解 加到类上 则这个类的所有方法就都有事务了 但是你可以在查询方法上再加一次Transactional注解并且设置只读模式提高效率2、超时时间 事务在执行过程中可能会由于某些问题导致卡住从而长时间占用数据库资源 而长时间占用数据库资源大概率是因为程序出现了问题(可能是Java程序、Mysql数据库、网络连接等问题)此时这个很可能出现问题的程序就应该被回滚撤销他已做的操作事务结束把资源让出来让其他程序可以正常执行 总之就是超时回滚、释放资源 默认永不超时值是-1 设置timeout 秒数超时后就会回滚事务和释放异常 超时的异常是TransactionTimedOutException如果类上设置了Transactional注解 和 这个timeout属性 并且方法上也设置了Transactional注解但是没有设置timeout属性 那么此时方法上的timeout值是 默认值 -1哦3、指定异常回滚 和 指定异常不回滚 默认情况下发生运行时异常才会回滚 我们可以指定Exception异常来控制所有异常都会滚 rollbackForException.class意思是所有的异常都回滚 noRollbackForFileNotFoundException.class意思是指定FileNotFoundException异常不回滚Transactional(timeout3,rollbackForException.class,noRollbackForFileNotFoundException.class)publicvoidchangeInfo()throwsFileNotFoundException{studentDao.updatePloneById(1390002,1);加这句代码是为了测试事务是否加上了inti1/0;这句代码本身是会报错的 因为有事务的话即使inti1/0;这句代码上面的代码没有错但是inti1/0;报错了 会造成回滚所以整个方法里的代码都不会生效。 但是如果没有事务的话inti1/0;这句代码上面正确的代码会执行生效的// int i 1/0;// try {// Thread.sleep(5000); // 等5秒为了测试 timeout这个属性// } catch (InterruptedException e) {// throw new RuntimeException(e);// }测试异常回滚newFileInputStream(xxx);System.out.println(----------------------------);studentDao.updateNameById(springtx-改名,2);}事务传播行为 声明两个独立修改数据库的事务业务方法 propagationPropagation.REQUIRED意思是如果父方法有事务我们就加入到父方法的事务最终是同一个事务 如果父方法没有事务就新建自己独立的事务 propagationPropagation.REQUIRES_NEW意思是不管父方法是否有事务我都是独立的事务// 声明两个独立修改数据库的事务业务方法Transactional(propagationPropagation.REQUIRED)publicvoidchangeAge(){studentDao.updateAgeById(99,1);}Transactional(propagationPropagation.REQUIRED)publicvoidchangeName(){studentDao.updateNameById(test2,1);inti1/0;}}TopService.java声明一个整合业务方法ServicepublicclassTopService{AutowiredprivateStudentServicestudentService;// 声明一个整合业务方法TransactionalpublicvoidtopService(){studentService.changeAge();studentService.changeName();}}添加传播行为测试SpringJUnitConfig(classesJavaConfig.class)publicclassTxTest{AutowiredprivateTopServicetopService;TestpublicvoidtestTx()throwsFileNotFoundException{topService.topService();}}解释在这个例子中TopService的topService方法本身有一个事务因为Transactional默认传播行为是REQUIRED。当它调用StudentService的changeAge方法时由于changeAge的传播行为也是REQUIRED所以它会加入到现有的TopService的事务中而不是创建新事务。同样当调用changeName方法时同样会加入到TopService的事务中。当执行到changeName 方法中的 int i 1/0; 时会抛出ArithmeticException这是一个RuntimeException。Spring默认会对这种异常触发事务回滚。由于changeName和changeAge都在同一个事务中所以整个事务会回滚包括changeAge的更新 和changeName的更新。需要确认的是当多个方法在同一个事务中执行时如果其中一个方法抛出未检查异常整个事务会回滚。因此在这个例子中虽然changeAge方法本身没有抛出异常但由于changeName抛出了异常导致整个事务回滚所以changeAge的更新也会被撤销。