java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > spring注解开启声明式事务

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自增)

idname
1zhangsan

业务逻辑编写

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

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

您可能感兴趣的文章:
阅读全文