首页 > 其他分享 >Spring声明式事务

Spring声明式事务

时间:2024-08-09 15:06:59浏览次数:7  
标签:事务 Spring Transactional 方法 dataSource 声明 public 属性

Spring声明式事务

 

1.事务的概念

1.1编程式事务

编程式事务是指手动编写程序来管理事务,即通过编写代码的方式直接控制事务的提交和回滚

Connection conn = ...;
​
try{
    //开启事务:关闭事务的自动提交
    conn.setAutoCommit(false);
    //业务代码
    ...
    //提交事务
    conn.commit();
}catch{
    //事务回滚
    conn.rollBack();
}finally{
    //释放数据库连接
    conn.close();
}

编程式事务存在的缺陷:

  • 细节没有被屏蔽:具体操作过程中,所有细节都需要程序员自己来完成,较为繁琐

  • 代码复用性不高:如果没有有效抽取出来,每次实现功能都需要自己编写代码,没有复用。

 

1.2声明式事务

声明式事务是指使用注解或xml配置的方式来控制事务的提交和回滚。

开发者只需要添加配置即可,具体事务的实现由第三方框架实现,避免我们直接进行事务操作。

在spring中 spring-tx是专门来做声明式事务的框架

 

1.3事务管理器

spring的tx是对aop的再次封装

tx不会在事务增强代码中写具体的事务实现,而是通过一个接口-事务管理器(具体提供事务方法)

在增强的对应的位置调用这个接口的方法

而这个接口的常用实现类spring也为我们提供了,在实现类中重写这个事务管理器的方法

常用事务管理器实现类:DataSourceTransactionManager、HibernateTransactionManager等

我们只需要把这些实现类配置到ioc容器中即可

image-20240809091127927

 

2.事务操作

2.1添加事务

  • 选择对应的事务管理器实现类加入到ioc容器

    在配置类中,通过@Bean 注解加入到ioc容器,还要再配置类上使用 @EnableTransactionManagement

    @Configuration
    @ComponentScan("com.ztone")
    @PropertySource("classpath:jdbc.properties")
    @EnableTransactionManagement
    public class JavaConfig {
    ​
        @Value("${url}")
        private String url;
        @Value("${driver}")
        private String driver;
        @Value("${username1}")
        private String username;
        @Value("${password}")
        private String password;
    ​
        @Bean
        public DataSource dataSource(){
            DruidDataSource dataSource = new DruidDataSource();
            dataSource.setUrl(url);
            dataSource.setDriverClassName(driver);
            dataSource.setUsername(username);
            dataSource.setPassword(password);
            return dataSource;
        }
    ​
        @Bean
        public JdbcTemplate jdbcTemplate(DataSource dataSource){
            JdbcTemplate jdbcTemplate = new JdbcTemplate();
            jdbcTemplate.setDataSource(dataSource);
            return jdbcTemplate;
        }
    ​
        @Bean
        public TransactionManager transactionManager(DataSource dataSource){
            DataSourceTransactionManager transactionManager = new DataSourceTransactionManager();
            //事务操作需要连接池对象
            transactionManager.setDataSource(dataSource);
            return transactionManager;
        }
    }
  • 使用注解指定哪些方法需要添加事务

    在需要添加事务的方法或类上使用 @Transactional

    @Service
    public class StudentService {
    ​
        @Autowired
        private StudentDao studentDao;
    ​
        @Transactional
        public void updateStudent(){
            studentDao.updateNameById("zhangsan",1);
            int result = 1/0;
            studentDao.updateAgeById(200,1);
        }
    }

当事务中出现错误,就不会提交

 

 

2.2属性:只读

在 @Transactional 注解中有一个属性是 readonly 表示只读模式,可以提升查询的效率,但是开启只读模式后,不能进行修改的操作,否则会报错。默认值是false,不开启。

所以只读模式只是用在查询操作上。

应用场景:一般@Transactional 注解都用在类上,所以该类所有方法都有事务,那么我们可以在查询的方法上将readonly 属性设置为true,提升查询的效率。

 

2.3属性:超时时间

在@Transactional 注解中有 timeout 属性,可以设置等待的秒数,如果超过了这个秒数就会回滚事务和释放异常

这个属性如果写在类上,需要保证方法上没有这个注解,否则不会生效

 

2.4属性:事务异常指定

在默认情况下,只有发生运行时异常时事务才会回滚。

我们可以通过 指定 rollbackFor的值 来控制什么异常进行回滚,通常指定rollbackFor 的值为 Exception,所有异常都回滚。

与之对应的是 noRollbackFor ,指定某个异常不回滚

@Transactional(rollbackFor = Exception.class)
public void updateStudent(){
    studentDao.updateNameById("zs",1);
    int result = 1/0;
    studentDao.updateAgeById(1000,1);
}

 

2.5属性:事务隔离级别

数据库事务的隔离级别是指在多个事务并发执行时,数据库系统为了保证数据一致性所遵循的规定。常见的隔离级别包括:

  • 读未提交:事务可以读取未被提交的数据,容易产生脏读、不可重复度、幻读等,实现简单但不太安全,一般不用。

  • 读已提交:事务只能读取已经提交的的数据,可以避免脏读的问题,但可能引发不可重复读和幻读

  • 可重复读:在一个事务中,相同的查询将返回相同的结果集,不管其他事务对数据做了什么修改。可以避免脏读和不可重复读,但仍有幻读问题。

  • 串行化:最高的隔离级别,完全禁止了并发,只允许一个事务执行完毕后才执行另一个事务,可以避免以上所有问题,但效率较低。不适用于高并发。

属性名 isolation

给该属性设置不同的枚举类型 以设置不同的隔离级别

读已提交--READ_COMMITTED

读未提交--READ_UNCOMMITTED

串行化--SERIALIZABLE

可重复读--REPEATABLE_READ

在mysql中 Isolation.DEFAULT 是 可重复读

 

2.6属性:事务的传播行为

现在有两个业务方法,每个业务方法都添加了事务,当在业务方法1中调用了业务方法2,那么业务方法2的事务会加入到业务方法1的事务中还是会独立出来,就是由事物的传播行为来指定

事务传播行为的属性需要设置到子事务上

属性:propagation

  • REQUIRED:如果父方法中有事务,子方法就加入到父方法的事务中,如果没有就自己创建一个事务,最终只有一个事务

  • REQUIRES_NEW:不管父方法是否有事务,子方法都创建自己的事务,都是独立的事务。

  • NESTED:如果当前存在事务,则在该事务中嵌套一个新事务,吴国没有则与 REQUIRED 一样

  • SUPPORTS:如果当前存在事务,则加入该事务,否则以非事务方式运行

  • NOT_SUPPORTED:以非事务方式执行,如果当前存在事务,挂起该事务

  • MANDATORY:必须在一个已有的事务中执行,否则会抛异常

  • NEVER:必须在没有事务的情况下执行,否则抛异常

 

在同一个类中,对于@Transactional注解的方法的调用,事务传播行为不会生效,因为Spring框架中使用代理模式实现事务机制,在同一个类没办法生成代理对象,所以不会产生事务传播行为。

标签:事务,Spring,Transactional,方法,dataSource,声明,public,属性
From: https://www.cnblogs.com/wztblogs/p/18350779

相关文章

  • 如何关闭redis的自动清理缓存,声明式事务(含有redis)如何解决,redis setnx锁的使用。
    20240809一、解决redis数据被删除的方案1、发现问题2、解决注意!!二、声明式事务(当有redis的时候)1.先看代码2.@Transactional(rollbackFor=Exception.class)3.如何解决redis在事务里面,如何保证原子性和一致性3.1我们可以用trycatchfinally来实现3.2我们可以让red......
  • Spring中的统一异常处理
    在具体的SSM项目开发中,由于Controller层为处于请求处理的最顶层,再往上就是框架代码的。因此,肯定需要在Controller捕获所有异常,并且做适当处理,返回给前端一个友好的错误码。不过,Controller一多,我们发现每个Controller里都有大量重复的、冗余的异常处理代码,很是啰嗦。能否将这些......
  • 新建一个SpringMVC项目
    新建一个SpringMVC项目一、思路需求分析,主要考虑用例图、活动图建数据库新建maven项目设置项目的web框架pom.xml中导入依赖包,数据库、连接池、mybatis,mybatis-spring、spring、junit编写spring主配置文件applicationContext.xml,用于整合框架编写web.xml文件,DispatcherSer......
  • springcloud alibaba sentinel降级 @SentinelResource
    1.sentinel降级方法和主方法public且返回值、参数必须一致的情况下,必须加【BlockExceptionblockException】参数2、业务降级方法和主方法public且返回值、参数必须一致,Throwable参数可加可不加@RequestMapping("/consumer/fallback/{id}")@SentinelResource(value=......
  • Springboot+logback+druid +密码加密 实现业务日志入库
    springboot配置spring:datasource:type:com.alibaba.druid.pool.DruidDataSourcedruid:#主库数据源master:driverClassName:com.mysql.cj.jdbc.Driverurl:jdbc:mysql://xxx:3306/dbName?useUnicode=true&characterEncoding=u......
  • spring boot下跨域安全配置
    1@Bean2publicFilterRegistrationBeancorsFilter(){3finalUrlBasedCorsConfigurationSourcesource=newUrlBasedCorsConfigurationSource();4finalCorsConfigurationconfig=newCorsConfiguration();5config.setAll......
  • IntelliJ IDEA 2024.2 发布:Spring Data JPA即时查询、自动补全cron表达式
    今早看到,IntelliJIDEA2024.2发布的邮件提示,看了一眼这个版本更新的新特性真的太适合我了!也许这些能力对关注DD的小伙伴也有帮助,所以搞篇博客介绍和推荐一下。下面就来一起看看这个版本中推出的几个强大新特性。SpringDataJPA的即时查询在2024.2Ultimate版本中,对Spring......
  • SpringCloud服务注册与发现的实现原理
    SpringCloud是一个分布式系统开发的框架,其中的服务注册与发现是其核心功能之一。在分布式系统中,服务的注册与发现是非常重要的,它可以帮助系统自动地发现和管理各个服务之间的依赖关系,提高系统的可扩展性和可靠性。SpringCloud基于Netflix的开源组件Eureka来实现服务的注册......
  • SpringCloud Gateway
    基于从前的项目:https://www.cnblogs.com/xsj1989/p/18338930参考文章:https://blog.csdn.net/hong161688/article/details/140812734官网文档:https://cloud.spring.io/spring-cloud-gateway/reference/html/新建一个Module,cloud-gateway-centerpom引入包<!--SpringCloud......
  • 一个基于SpringBoot实现的图像托管程序
    大家好,我是Java陈序员。今天,给大家介绍一个基于SpringBoot实现的开源图床项目。关注微信公众号:【Java陈序员】,获取开源项目分享、AI副业分享、超200本经典计算机电子书籍等。项目介绍Tbed——一个由Java语言编写、SpringBoot框架开发的开源图像托管程序。具备多对象......