<
>

spring 注解如何开启声明式事务

2022-12-28 11:07:34 来源:易采站长站 作者:

目录spring开启声明式事务导入依赖配置类文件业务逻辑编写测试代码总结spring开启声明式事务导入依赖pom.xmldependencies!--https://mvnrepos...

目录
spring开启声明式事务
导入依赖
配置类文件
业务逻辑编写
测试代码
总结

spring开启声明式事务

导入依赖

pom.XML

<dependencies>
    <!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
    <!--spring依赖-->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>4.3.12.RELEASE</version>
    </dependency>
    <!--单元测试依赖-->
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.13</version>
      <scope>test</scope>
    </dependency>

    <!--mysql驱动-->
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-Java</artifactId>
      <version>8.0.21</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/c3p0/c3p0 -->
    <!--c3p0数据源-->
    <dependency>
      <groupId>c3p0</groupId>
      <artifactId>c3p0</artifactId>
      <version>0.9.1.2</version>
    </dependency>
    <!--spring jdbc spring操作数据库-->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-jdbc</artifactId>
      <version>4.3.12.RELEASE</version>
    </dependency>
  </dependencies>

操作数据库需要配置数据源,spring提供的操作数据库的JdbcTemplate创建时需要传入数据源,事务管理器创建时也需要传入数据源,然后将数据源,JdbcTemplate,事务管理器注册到容器中

具体代码如下:

配置类文件

SpringTxConfig.java

package com.sixteen.tx;

import com.mchange.v2.c3p0.ComboPooledDataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import javax.sql.DataSource;
import java.beans.PropertyVetoException;

@ComponentScan(basePackages = {"com.sixteen.tx"})//包扫描
@Configuration
@EnableTransactionManagement//开启基于注解的声明式事务
public class SpringTxConfig {

 //注册数据源
  @Bean
  public DataSource dataSource() throws PropertyVetoException {
    ComboPooledDataSource dataSource = new ComboPooledDataSource();
    dataSource.setDriverClass("com.mysql.cj.jdbc.Driver");
    dataSource.setPassword("123456");
    dataSource.setUser("root");
    dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/jdbc?serverTimezone=Asia/Shanghai&useSSL=true&useUnicode=true&characterEncoding=UTF-8");
    return dataSource;
  }

 //注册JdbcTemplate
  @Bean
  public JdbcTemplate jdbcTemplate() throws PropertyVetoException {
    //两种方法获取DataSource
    //1. 直接在方法放置参数 public JdbcTemplate jdbcTemplate(DataSource dataSource)
    //   默认会去容器中获取
    //2. 如下: 调用上面的方法


    //spring对@Configuration类有特殊处理,注册组件的方法多次调用只是在IOC容器中找组件
    return new JdbcTemplate(dataSource());
  }

  //注册事务管理器
  @Bean
  public PlatformTransactionManager transactionManager() throws PropertyVetoException {
    return new DataSourceTransactionManager(dataSource());//需要传入dataSource
  }
}

ps: 我用的mysql是8.0+版本,编写jdbcUrl时至少需要附带时区参数:serverTimezone=Asia/Shanghai

在此之前需要在mysql数据库中建一张普通的User表,如下所示:(id自增)

idname1zhangsan

业务逻辑编写

UserDao.java

package com.sixteen.tx;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;

import java.util.UUID;

@Repository
public class UserDao {

    @Autowired
    private JdbcTemplate jdbcTemplate;

    public void insert(){
        String sql = "INSERT INTO `user`(name) VALUES(?)";
        String name = UUID.randomUUID().toString().substring(0, 5);
        jdbcTemplate.update(sql,name);
    }
}

UserService.java

package com.sixteen.tx;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
public class UserService {

  @Autowired
  private UserDao userDao;

  @Transactional
  public void insertUser(){
    userDao.insert();
    System.out.println("插入完成");
    //故意制造错误,使事务生效,进行回滚
    int i = 10/0;
  }
}


测试代码

SpringTxTest.java

package com.sixteen.test;

import com.sixteen.tx.SpringTxConfig;
import com.sixteen.tx.UserService;
import org.junit.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class SpringTxTest {
  @Test
  public void testInsert(){
    AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringTxConfig.class);
    UserService service = context.getBean(UserService.class);
    service.insertUser();
  }
}

总结

以上就是spring如何用注解方式开启声明式事务,细节之处可能没有讲到,但基本的实现还是有的,若有不足之处望见谅并指出。

这些仅为个人经验,希望能给大家一个参考,也希望大家多多支持我们。

暂时禁止评论

微信扫一扫

易采站长站微信账号