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

目录
  • 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自增)

id name
1 zhangsan

业务逻辑编写

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如何用注解方式开启声明式事务,细节之处可能没有讲到,但基本的实现还是有的,若有不足之处望见谅并指出。

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

(0)

相关推荐

  • Spring深入刨析声明式事务注解的源码

    目录 1.@EnableTransactionManagement 2.加载事务控制组件 2.1.AutoProxyRegistrar 2.2.ProxyTransactionManagementConfiguration 组件 2.3.上述组件如何关联起来的 2.4.invokeWithinTransaction⽅法 声明式事务很方便,尤其纯注解模式,仅仅几个注解就能控制事务了 思考:这些注解都做了什么?好神奇! @EnableTransactionManagement @Transactio

  • Spring实战之使用注解实现声明式事务操作示例

    本文实例讲述了Spring实战之使用注解实现声明式事务操作.分享给大家供大家参考,具体如下: 一 配置文件 <?xml version="1.0" encoding="GBK"?> <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/beans" xm

  • springboot开启声明式事务的方法

    springboot开启事务很简单,只需要一个注解@Transactional 就可以了.因为在springboot中已经默认对jpa.jdbc.mybatis开启了事事务,引入它们依赖的时候,事物就默认开启.当然,如果你需要用其他的orm,比如beatlsql,就需要自己配置相关的事物管理器. 准备阶段 以上一篇文章的代码为例子,即springboot整合mybatis,上一篇文章是基于注解来实现mybatis的数据访问层,这篇文章基于xml的来实现,并开启声明式事务. 环境依赖 在pom文件

  • spring是如何实现声明式事务的

    前言 今天我们来讲讲spring的声明式事务. 开始 说到声明式事务,我们现在回顾一下事务这个概念,什么是事务呢,事务指的是逻辑上的⼀组操作,组成这组操作的各个单元,要么全部成功,要么全部不成功.从而确保了数据的准确与安全.事务有着四大特性(ACID),分别是 原子性(Atomicity)原⼦性是指事务是⼀个不可分割的⼯作单位,事务中的操作要么都发⽣,要么都不发⽣. ⼀致性(Consistency)事务必须使数据库从⼀个⼀致性状态变换到另外⼀个⼀致性状态. 隔离性(Isolation)事务的隔离

  • Spring声明式事务注解之@EnableTransactionManagement解析

    Spring声明式事务注解之@EnableTransactionManagement 1. 说明 @EnableTransactionManagement声明在主配置类上,表示开启声明式事务,其原理是通过@Import导入TransactionManagementConfigurationSelector组件,然后又通过TransactionManagementConfigurationSelector导入组件AutoProxyRegistrar和ProxyTransactionManageme

  • Spring实现声明式事务的方法详解

    1.回顾事务 事务在项目开发过程非常重要,涉及到数据的一致性的问题,不容马虎! 事务管理是企业级应用程序开发中必备技术,用来确保数据的完整性和一致性. 事务就是把一系列的动作当成一个独立的工作单元,这些动作要么全部完成,要么全部不起作用. 事务四个属性ACID 原子性(atomicity) 事务是原子性操作,由一系列动作组成,事务的原子性确保动作要么全部完成,要么完全不起作用. 一致性(consistency) 一旦所有事务动作完成,事务就要被提交.数据和资源处于一种满足业务规则的一致性状态中.

  • SpringBoot 注解事务声明式事务的方式

    springboot 对新人来说可能上手比springmvc要快,但是对于各位从springmvc转战到springboot的话,有些地方还需要适应下,尤其是xml配置.我个人是比较喜欢注解➕xml是因为看着方便,查找方便,清晰明了.但是xml完全可以使用注解代替,今天就扒一扒springboot中事务使用注解的玩法. springboot的事务也主要分为两大类,一是xml声明式事务,二是注解事务,注解事务也可以实现类似声明式事务的方法,关于注解声明式事务,目前网上搜索不到合适的资料,所以在这里

  • spring声明式事务解析

    一.spring声明式事务 1.1 spring的事务管理器 spring没有直接管理事务,而是将管理事务的责任委托给JTA或相应的持久性机制所提供的某个特定平台的事务实现.spring容器负责事物的操作,spring容器充当切面,事务的方法称为增强处理,生成的代理对象的方法就是目标方法+增强也就是crud+事务程序员只用做crud的操作,也就是目标方法和声明哪些方法应该在事务中运行. Spring提供了许多内置事务管理器实现: DataSourceTransactionManager:位于or

  • 详解Spring学习之声明式事务管理

    前言 在前面的小节中,我们学习了关于事务的概念以及事务管理的重要性,并且通过编程使用Spring的编程式事务管理进行操作,加深对事务管理的重要性的学习,不过,由于编程式的事务管理使用起来不是很方便,所以在日常的开发中基本不怎么使用,接下来的内容我们将学习使用Spring的声明式事务管理,这里有一个地方需要明白的是,Spring的声明式事务管理的实现方式其实是通过AOP的方式来实现的,也就是为原始的事务管理对象创建代理对象,从而实现事务管理增强的 基于TransactionProxyFactory

  • 完美解决Spring声明式事务不回滚的问题

    疑问,确实像往常一样在service上添加了注解 @Transactional,为什么查询数据库时还是发现有数据不一致的情况,想想肯定是事务没起作用,出现异常的时候数据没有回滚.于是就对相关代码进行了一番测试,结果发现一下踩进了两个坑,确实是事务未回滚导致的数据不一致. 下面总结一下经验教训: Spring事务的管理操作方法 编程式的事务管理 实际应用中很少使用 通过使用TransactionTemplate 手动管理事务 声明式的事务管理 开发中推荐使用(代码侵入最少) Spring的声明式事

随机推荐