【第16章】spring-tx基于注解的声明式事务


前言

Spring-tx是Spring框架提供的事务管理模块,它为DB事务管理提供了一种便捷的接入方式。它允许应用程序开发人员在任何环境中使用一致的编程模型,通过编程事务管理或声明式事务管理来简化事务处理的复杂性。

编程事务管理允许开发人员使用Spring框架的事务抽象,该抽象可以运行在任何底层事务基础设施上。而声明式事务管理则是一种更为简洁的方式,开发人员通常很少或不编写与事务管理相关的代码,因此不依赖于Spring Framework事务API或任何其他事务API。

Spring-tx对用户提供统一的声明式事务、编程式事务解决方案,对事务的入口、定义、传播、提交、回滚进行了封装,与业务代码隔离。它抽象出事务操作PlatformTransactionManager顶级接口,通过将连接及其他需要同步的资源交由事务同步管理器(TransactionSynchronizationManager->ThreadLocal)管理。

事务的特性包括原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)和持久性(Durability)。原子性指的是事务中的所有操作要么全部完成,要么全部不完成;一致性确保在事务开始和结束时,数据库的完整性限制没有被破坏;隔离性确保两个事务的执行互不干扰;持久性保证事务完成后对数据库的更改被持久保存。

总的来说,Spring-tx通过简化和统一事务管理的方式,使开发人员能够更专注于业务逻辑的实现,而无需过多关注底层的事务处理细节。


一、准备

1. 数据库

create table user(
	id int primary key auto_increment,
	name varchar(255),
	age int,
	address varchar(255)
)charset utf8;
INSERT INTO `test`.`user`(`id`, `name`, `age`, `address`) VALUES (1, '张三', 22, '北京');
INSERT INTO `test`.`user`(`id`, `name`, `age`, `address`) VALUES (2, '李四', 23, '邯郸');

二、后台代码

业务描述:有一个需求,用户编号销户则编号释放,将原账户编号注册为新用户(一个删,一个增)

1. 业务类

1.1 controller

package org.example.tx.annotation.controller;

import org.example.tx.annotation.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;

/**
 * Create by zjg on 2024/4/14
 */
@Controller
public class UserController {
    @Autowired
    UserService userService;
    public boolean destory(int id){
       return userService.destory(id);
    }
}

1.2 service

1.2.1 service

package org.example.tx.annotation.service;

/**
 * Create by zjg on 2024/4/14
 */
public interface UserService {
    public boolean destory(int id);
}

1.2.2 impl

package org.example.tx.annotation.service.impl;

import org.example.tx.annotation.dao.UserDao;
import org.example.tx.annotation.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * Create by zjg on 2024/4/14
 */
@Service
public class UserServiceImpl implements UserService {
    @Autowired
    UserDao userDao;
    @Transactional
    @Override
    public boolean destory(int id){
        int delete = userDao.delete(id);
//        int i=1/0;
        int add = userDao.add(id);
        if(delete==1&&add==1){
            return true;
        }
        return false;
    }
}

1.3 dao

1.3.1 dao

package org.example.tx.annotation.dao;

/**
 * Create by zjg on 2024/4/14
 */
public interface UserDao {
    public int delete(int id);
    public int add(int id);
}

1.3.2 impl

package org.example.tx.annotation.dao.impl;

import org.example.tx.annotation.dao.UserDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;

/**
 * Create by zjg on 2024/4/14
 */
@Repository
public class UserDaoImpl implements UserDao {
    @Autowired
    JdbcTemplate jdbcTemplate;
    @Override
    public int delete(int id) {
        String sql="delete from user where id=?";
        return jdbcTemplate.update(sql, id);
    }

    @Override
    public int add(int id) {
        String sql="insert into user value(?,?,?,?)";
        return jdbcTemplate.update(sql, id, "张三", 30, "石家庄");
    }
}

2.配置类

2.1 jdbc.properties

jdbc_driverClassName=com.mysql.cj.jdbc.Driver
jdbc_url=jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=GMT%2B8&allowPublicKeyRetrieval=true
jdbc_username=root
jdbc_password=123456a?

2.2 SpringConfig

package org.example.tx.annotation.config;

import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;

/**
 * Create by zjg on 2024/4/14
 */
@Configuration
@ComponentScan("org.example.tx.annotation")
@EnableTransactionManagement
@PropertySource("classpath:jdbc.properties")
public class SpringConfig {
    @Value("${jdbc_driverClassName}")
    private String driverClassName;

    @Value("${jdbc_url}")
    private String url;

    @Value("${jdbc_username}")
    private String username;

    @Value("${jdbc_password}")
    private String password;
    @Bean
    public DruidDataSource dataSource(){
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setDriverClassName(driverClassName);
        dataSource.setUrl(url);
        dataSource.setUsername(username);
        dataSource.setPassword(password);
        return dataSource;
    }
    @Bean
    public JdbcTemplate jdbcTemplate(DruidDataSource dataSource){
        JdbcTemplate jdbcTemplate = new JdbcTemplate();
        jdbcTemplate.setDataSource(dataSource);
        return jdbcTemplate;
    }
    @Bean
    public DataSourceTransactionManager transactionManager(DruidDataSource dataSource){
        DataSourceTransactionManager transactionManager = new DataSourceTransactionManager();
        transactionManager.setDataSource(dataSource);
        return transactionManager;
    }
}

2.3 SpringApplication

package org.example.tx.annotation;

import org.example.tx.annotation.config.SpringConfig;
import org.example.tx.annotation.controller.UserController;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

/**
 * Create by zjg on 2024/4/14
 */
public class SpringApplication {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext acac = new AnnotationConfigApplicationContext(SpringConfig.class);
        UserController userController = acac.getBean("userController", UserController.class);
        userController.destory(1);
    }
}

三、扩展

1. 特性

属性 描述
原子性(Atomicity) 事务被视为不可分割的最小工作单位,事务中的操作要么全部完成,要么全部不完成,不可能只执行其中的一部分操作。
一致性(Consistency) 事务必须使数据库从一个一致性状态变换到另一个一致性状态。也就是说,一个事务执行前后,数据必须保持一致。
隔离性(Isolation) 在事务执行过程中,多个事务并发执行时,一个事务的执行不应影响其他事务。即一个事务内部的操作及使用的数据对其他并发事务是隔离的,并发执行的各个事务之间不能互相干扰。
持久性(Durability) 持久性也称永久性(Permanence),指一个事务一旦提交,它对数据库中数据的改变就应该是永久性的。接下来的其他操作或故障不应该对其执行结果有任何影响。

2. 隔离级别

隔离级别 描述
读未提交(Read Uncommitted) 事务可以读取未提交的其他事务的修改。这种隔离级别可能会导致脏读、不可重复读和幻读问题。
读已提交(Read Committed) 一个事务只能读取已经提交的其他事务的修改。这可以防止脏读,但可能会出现不可重复读和幻读问题。
可重复读(Repeatable Read) 在同一事务内,多次读取同一数据返回的结果是一致的。这可以防止脏读和不可重复读,但可能会出现幻读问题。
串行化(Serializable) 最严格的隔离级别,它通过对事务进行排序,使之不可能相互冲突,从而解决脏读、不可重复读和幻读问题。但这也可能导致性能问题,因为事务只能一个接一个地执行。

3. 传播行为

传播行为 描述
PROPAGATION_REQUIRED 如果当前没有事务,就创建一个新事务;如果当前存在事务,就加入该事务。这是最常用的设置。
PROPAGATION_SUPPORTS 支持当前事务,如果当前存在事务,就加入该事务;如果当前不存在事务,就以非事务方式执行。
PROPAGATION_MANDATORY 支持当前事务,如果当前存在事务,就加入该事务;如果当前不存在事务,就抛出异常。
PROPAGATION_REQUIRES_NEW 创建新事务,无论当前是否存在事务,都创建新事务。
PROPAGATION_NOT_SUPPORTED 以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
PROPAGATION_NEVER 以非事务方式执行,如果当前存在事务,则抛出异常。
PROPAGATION_NESTED 如果当前存在事务,则在嵌套事务内执行;如果当前没有事务,就执行PROPAGATION_REQUIRED行为。

总结

回到顶部

相关推荐

  1. 16spring-tx基于注解声明事务

    2024-04-23 20:52:01       13 阅读
  2. Spring事务核心:声明事务&注解事务

    2024-04-23 20:52:01       20 阅读
  3. spring事务(3)基于XML声明事务

    2024-04-23 20:52:01       38 阅读
  4. spring基于XML声明事务控制

    2024-04-23 20:52:01       12 阅读
  5. Spring 声明事务

    2024-04-23 20:52:01       40 阅读
  6. Spring 声明事务

    2024-04-23 20:52:01       41 阅读
  7. Spring声明事务

    2024-04-23 20:52:01       34 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-04-23 20:52:01       16 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-04-23 20:52:01       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-04-23 20:52:01       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-04-23 20:52:01       18 阅读

热门阅读

  1. NLP(5)-softmax和交叉熵

    2024-04-23 20:52:01       13 阅读
  2. web server apache tomcat11-15-proxy

    2024-04-23 20:52:01       12 阅读
  3. wsl ubuntu18.04升级为cmake-3.15.3

    2024-04-23 20:52:01       13 阅读
  4. 前端宝藏图:寻找技术之旅的星辰大海

    2024-04-23 20:52:01       12 阅读
  5. Python爬取网易云平台

    2024-04-23 20:52:01       13 阅读