Spring JPA事务管理与自定义操作实例解析(最新推荐)

 更新时间:2024年12月24日 12:08:09   作者:t0_54coder  
在Spring框架中,数据持久化操作常常与事务管理紧密相关,本文将深入探讨Spring Data JPA中的事务管理机制,并结合具体实例,展示如何自定义事务行为以满足不同的业务需求,感兴趣的朋友一起看看吧

在Spring框架中,数据持久化操作常常与事务管理紧密相关。本文将深入探讨Spring Data JPA中的事务管理机制,并结合具体实例,展示如何自定义事务行为以满足不同的业务需求。

Spring JPA中的事务管理

在Spring Data JPA中,默认的CrudRepository实现是SimpleJpaRepository。这个类通过@Transactional注解支持事务管理,其中readOnly = true属性意味着默认情况下所有方法都在只读事务中执行。对于写操作,如deleteByIddeleteAll等,它们通过@Transactional注解覆盖了只读行为,使得这些方法在写事务中执行。

@Repository
@Transactional(readOnly = true)
public class SimpleJpaRepository<T, ID> implements JpaRepository<T, ID>, JpaSpecificationExecutor<T> {
    @Transactional
    public void deleteById(ID id) {...}
    // 其他写操作
}

自定义Repository事务行为

若要自定义事务设置,我们可以重写特定的方法,并添加@Transactional注解。例如,我们可以为deleteById方法设置一个超时时间:

public interface EmployeeRepository extends CrudRepository<Employee, Long> {
    @Transactional(timeout = 10)
    @Override
    public void deleteById(ID id);
}

在Repository外部使用事务

在Repository外部使用事务,需要在配置类上添加@EnableTransactionManagement注解:

@Configuration
@ComponentScan
@EnableTransactionManagement
public class AppConfig {
    // ...
}

然后,我们可以在服务类中使用@Transactional注解来管理事务:

@Service
public class MyExampleBean{
    @Transactional
    public void saveChanges() {
        repo.save(..);
        repo.deleteById(..);
        .....
    }
}

实例分析

Entity定义

@Entity
public class Employee {
    @Id
    @GeneratedValue
    private Long id;
    @Column(unique = true)
    private String name;
    private String dept;
    private int salary;
    // 省略其他字段和方法
}

Repository定义

public interface EmployeeRepository extends CrudRepository<Employee, Long> {
    @Transactional(timeout = 10)
    @Override
    <S extends Employee> S save(S s);
}

客户端操作

@Component
public class ExampleClient {
    @Autowired
    private EmployeeRepository repo;
    public void findEmployees() {
        System.out.println(" -- finding all employees --");
        repo.findAll().forEach(System.out::println);
    }
    @Transactional
    public void saveEmployees() {
        repo.save(Employee.create("Mike", "Sale", 1000));
        repo.save(Employee.create("Diana", "Admin", 3000));
        repo.save(Employee.create("Diana", "IT", 3200)); // 这将触发异常
    }
}

在上面的saveEmployees方法中,我们尝试保存具有重复名称的员工。由于Employee实体类中通过@Column(unique = true)指定了唯一列,最后一个保存调用将失败,整个事务将回滚。如果不使用@Transactional注解,前两名员工仍然会被保存,即整个保存过程不会是原子性的。

JavaConfig配置

@EnableJpaRepositories
@ComponentScan
@Configuration
@EnableTransactionManagement
public class AppConfig {
    @Bean
    EntityManagerFactory entityManagerFactory() {
        EntityManagerFactory emf =
                Persistence.createEntityManagerFactory("example-unit");
        return emf;
    }
    @Bean
    public PlatformTransactionManager transactionManager() {
        JpaTransactionManager txManager = new JpaTransactionManager();
        txManager.setEntityManagerFactory(entityManagerFactory());
        return txManager;
    }
}

主类

public class ExampleMain {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context =
                new AnnotationConfigApplicationContext(AppConfig.class);
        ExampleClient exampleClient = context.getBean(ExampleClient.class);
        try {
            exampleClient.saveEmployees();
        } catch (Exception e) {
            System.err.println(e);
        }
        exampleClient.findEmployees();
        EntityManagerFactory emf = context.getBean(EntityManagerFactory.class);
        emf.close();
    }
}

如果不在saveEmployees方法上使用@Transactional注解,那么即使触发了唯一性约束异常,前两名员工的数据仍然会被保存,这违背了事务的原子性原则。

通过上述分析,我们可以看到Spring JPA事务管理的灵活性和强大功能,以及如何通过自定义事务行为来满足复杂的业务需求。

到此这篇关于Spring JPA事务管理与自定义操作实例解析的文章就介绍到这了,更多相关Spring JPA事务管理内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • SpringBoot项目启动错误:找不到或无法加载主类的几种解决方法

    SpringBoot项目启动错误:找不到或无法加载主类的几种解决方法

    本文主要介绍了SpringBoot项目启动错误:找不到或无法加载主类的几种解决方法,具有一定的参考价值,感兴趣的可以了解一下
    2025-03-03
  • 图解Java排序算法之希尔排序

    图解Java排序算法之希尔排序

    这篇文章主要为大家详细介绍了Java排序算法之希尔排序,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-11-11
  • Java实现时间与字符串互相转换详解

    Java实现时间与字符串互相转换详解

    这篇文章主要为大家详细介绍了Java中实现时间与字符串互相转换的相关方法,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
    2025-04-04
  • Java中反射的应用

    Java中反射的应用

    这篇文章主要介绍了Java中反射的应用,通过反射,我们可以在运行时检查类的属性、方法和构造函数,并且可以在不知道类名的情况下创建对象、调用方法和访问属性,需要的朋友可以参考下
    2023-10-10
  • Java实现角色扮演游戏的示例代码

    Java实现角色扮演游戏的示例代码

    这篇文章主要介绍了通过Java语言实现的自制的角色扮演游戏,选择两个角色,然后进行PK,可用来学习JAVA的接口,继承和多态。需要的可以参考一下
    2022-02-02
  • SpringBoot中使用Quartz管理定时任务的方法

    SpringBoot中使用Quartz管理定时任务的方法

    这篇文章主要介绍了SpringBoot中使用Quartz管理定时任务的方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-09-09
  • 详解Java面向对象中的继承

    详解Java面向对象中的继承

    这篇文章主要介绍了详解Java面向对象中的继承,继承提高代码的复用性:通过继承,子类可以直接使用父类的属性和方法,不需要重复定义,需要的朋友可以参考下
    2023-05-05
  • jpa 使用@Column来定义字段类型

    jpa 使用@Column来定义字段类型

    这篇文章主要介绍了jpa使用@Column来定义字段类型,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-11-11
  • JDK都出到14了,你有什么理由不会函数式编程(推荐)

    JDK都出到14了,你有什么理由不会函数式编程(推荐)

    这篇文章主要介绍了JDK都出到14了,你有什么理由不会函数式编程,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-05-05
  • Java Validation Api实现原理解析

    Java Validation Api实现原理解析

    这篇文章主要介绍了Java Validation Api实现原理解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-09-09

最新评论