时间:2021-05-19
在Spring Boot事务管理中,实现自接口PlatformTransactionManager。
public interface PlatformTransactionManager { org.springframework.transaction.TransactionStatus getTransaction(org.springframework.transaction.TransactionDefinition transactionDefinition) throws org.springframework.transaction.TransactionException; void commit(org.springframework.transaction.TransactionStatus transactionStatus) throws org.springframework.transaction.TransactionException; void rollback(org.springframework.transaction.TransactionStatus transactionStatus) throws org.springframework.transaction.TransactionException;}当我们使用了spring-boot-starter-jdbc依赖的时候,框 架会自动默认注入DataSourceTransactionManager。所以我们不需要任何额外 配置就可以用@Transactional注解进行事务的使用。
jdbc事务管理器
在Service中,被 @Transactional 注解的方法,将支持事务。如果注解在类上,则整个类的所有方法都默认支持事务。
多事务管理器情况
一:可以通过实现TransactionManagementConfigurer接口,里面方法返回值是默认的事务管理器。
二:可以在具体执行方法上设置value
如果Spring容器中存在多个 PlatformTransactionManager 实例,并且没有实现接口TransactionManagementConfigurer 指定默认值,在我们在方法上使用注解 @Transactional 的时候,就必须要用value指定,如果不指定,则会抛出异常。
//@EnableTransactionManagement // 开启注解事务管理,等同于xml配置文件中的 <tx:annotation-driven />@SpringBootApplicationpublic class ProfiledemoApplication implements TransactionManagementConfigurer { @Resource(name="txManager2") private PlatformTransactionManager txManager2; // 手动创建事务管理器1 datasource框架会自动注入 //在Spring容器中,我们手工注解@Bean 将被优先加载,框架不会重新实例化其他的 PlatformTransactionManager 实现类。 @Bean(name = "txManager1") public PlatformTransactionManager txManager(DataSource dataSource) { return new DataSourceTransactionManager(dataSource); } // 创建事务管理器2 @Bean(name = "txManager2") public PlatformTransactionManager txManager2(EntityManagerFactory factory) { return new JpaTransactionManager(factory); } // 实现接口 TransactionManagementConfigurer 方法,其返回值代表在拥有多个事务管理器的情况下默认使用的事务管理器 @Override public PlatformTransactionManager annotationDrivenTransactionManager() { return txManager2; } public static void main(String[] args) { SpringApplication.run(ProfiledemoApplication.class, args); }}具体实现
@Componentpublic class DevSendMessage implements SendMessage { // 使用value具体指定使用哪个事务管理器 @Transactional(value="txManager1") @Override public void send() { System.out.println(">>>>>>>>Dev Send()<<<<<<<<"); send2(); } @Transactional public void send2() { System.out.println(">>>>>>>>Dev Send2()<<<<<<<<"); }}隔离级别
public enum Isolation { DEFAULT(TransactionDefinition.ISOLATION_DEFAULT), READ_UNCOMMITTED(TransactionDefinition.ISOLATION_READ_UNCOMMITTED), READ_COMMITTED(TransactionDefinition.ISOLATION_READ_COMMITTED), REPEATABLE_READ(TransactionDefinition.ISOLATION_REPEATABLE_READ), SERIALIZABLE(TransactionDefinition.ISOLATION_SERIALIZABLE); private final int value; Isolation(int value) { this.value = value; } public int value() { return this.value; }}指定方法:通过使用 isolation 属性设置,例如:
传播行为
所谓事务的传播行为是指,如果在开始当前事务之前,一个事务上下文已经存在,此时有若干选项可以指定一个事务性方法的执行行为。
我们可以看 org.springframework.transaction.annotation.Propagation 枚举类中定义了6个表示传播行为的枚举值:
public enum Propagation { REQUIRED(TransactionDefinition.PROPAGATION_REQUIRED), SUPPORTS(TransactionDefinition.PROPAGATION_SUPPORTS), MANDATORY(TransactionDefinition.PROPAGATION_MANDATORY), REQUIRES_NEW(TransactionDefinition.PROPAGATION_REQUIRES_NEW), NOT_SUPPORTED(TransactionDefinition.PROPAGATION_NOT_SUPPORTED), NEVER(TransactionDefinition.PROPAGATION_NEVER), NESTED(TransactionDefinition.PROPAGATION_NESTED); private final int value; Propagation(int value) { this.value = value; } public int value() { return this.value; }}REQUIRED :如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务。默认值。
SUPPORTS :如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务的方式继续运行。
MANDATORY :如果当前存在事务,则加入该事务;如果当前没有事务,则抛出异常。(强制放入事务中)
REQUIRES_NEW :创建一个新的事务,如果当前存在事务,则把当前事务挂起。(打印日志常用,即使前面回滚,该事务也会执行,记录报错信息)
NOT_SUPPORTED :以非事务方式运行,如果当前存在事务,则把当前事务挂起。
NEVER :以非事务方式运行,如果当前存在事务,则抛出异常。
NESTED :如果当前存在事务,则创建一个事务作为当前事务的嵌套事务来运行;如果当前没有事务,则该取值等价于 REQUIRED 。
指定方法:通过使用 propagation 属性设置,例如:
@Transactional(propagation = Propagation.REQUIRED)事务不回滚情况
只在发生未被捕获的 RuntimeException 时才回滚
catch抛出的异常,两次插入都会成功
@Override @Transactional public void insertandinsert(Staff staff) { staffDao.insert(staff); try { int i = 1 / 0; }catch (Exception e){ e.printStackTrace(); } staffDao.insert(staff); }在service层方法的catch语句中增加:TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();语句,手动回滚不会插入数据
@Override @Transactional public void insertandinsert(Staff staff) throws Exception { try { staffDao.insert(staff); int i=1/0; staffDao.insert(staff); }catch (Exception e){ TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); } }以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
Spring事务管理Spring支持两种方式的事务管理:编程式事务管理:通过TransactionTemplate手动管理事务,实际应用中很少使用,使用XML配
前言在前面的小节中,我们学习了关于事务的概念以及事务管理的重要性,并且通过编程使用Spring的编程式事务管理进行操作,加深对事务管理的重要性的学习,不过,由于
Spring事务隔离与事务传播的详解与对比Spring是SSH中的管理员,负责管理其它框架,协调各个部分的工作。今天一起学习一下Spring的事务管理。Spri
配置事务:使用的tx前缀的标签,导入tx的命名空间配置事务管理器,把事务管理器交给Spring管理:事务的策略transaction-manager:事务增强基
前言Spring并不直接管理事务,而是提供了多种事务管理器,他们将事务管理的职责委托给Hibernate或者JTA等持久化机制所提供的相关平台框架的事务来实现。