掘金日新计划 · 8 月更文挑战第6天--spring-声明式事务处理

103 阅读1分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第6天,点击查看活动详情

1.创建新工程

image.png

2.配置pom.xml

<!--    引入对应的依赖-->
    <dependencies>
<!--        引入spring上下文管理-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.2.6.RELEASE</version>
        </dependency>
<!--        引入spring jdbc-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>5.2.6.RELEASE</version>
        </dependency>
<!--        引入mysql连接-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.16</version>
        </dependency>
<!--        引入单元测试-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
<!--        引入springframework 测试-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>5.2.6.RELEASE</version>
        </dependency>
<!--        引入日志依赖,我们可以在控制台看到对应日志输出-->
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.2.3</version>
        </dependency>
<!--        引入切面依赖-->
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.9.5</version>
        </dependency>
    </dependencies>

3.resource下新建applicationContext.xml

image.png 配置如下: 引入对应的官方链接

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        https://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/tx
        https://www.springframework.org/schema/tx/spring-tx.xsd
        http://www.springframework.org/schema/aop
        https://www.springframework.org/schema/aop/spring-aop.xsd">

配置datasource[用于配置数据库连接信息]

<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
    <property name="url" value="jdbc:mysql://localhost:3306/imooc?useSSL=false&amp;useUnicode=true&amp;characterEncoding=UTF-8&amp;serverTimezone=Asia/Shanghai&amp;allowPublicKeyRetrieval=true"/>
    <property name="username" value="root"/>
    <property name="password" value="root"/>
</bean>

注入jdbcTemplate

<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
    <property name="dataSource" ref="dataSource"/>
</bean>

4.编写相关的逻辑代码

创建三层业务结构,分别为dao,service,entity image.png 表机构结构如下: image.png 我们在entity中,创建对应的字段属性和get,set方法

public class Employee {
    private Integer eno;
    //这边有很多属性,只列举一个就好,其他的都是同样的操作
    //get方法
    public Integer getEno() {
        return eno;
    }
    //set方法
    public void setEno(Integer eno) {
        this.eno = eno;
    }
 }

我们在dao中创建EmployeeDao文件,用于处理写入数据的方法

package com.imooc.spring.jdbc.dao;

import com.imooc.spring.jdbc.entity.Employee;
import org.springframework.jdbc.core.JdbcTemplate;

public class EmployeeDao {
    //引入jdbcTemplate
    private JdbcTemplate jdbcTemplate;
    //jdbcTemplate get方法
    public JdbcTemplate getJdbcTemplate() {
        return jdbcTemplate;
    }
    //jdbcTemplate set 方法
    public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }
    //定义写入数据方法
    public void insert(Employee employee){
        String sql = "insert into employee (eno,ename,salary,dname,hiredate) values (?,?,?,?,?)";
        jdbcTemplate.update(sql,new Object[]{employee.getEno(),employee.getEname(),employee.getSalary(),employee.getDname(),employee.getHiredate()});
    }
}

我们在service 设置EmpooyeeService文件,用于处理批量处理数据

package com.imooc.spring.jdbc.service;

import com.imooc.spring.jdbc.dao.EmployeeDao;
import com.imooc.spring.jdbc.entity.Employee;
import org.springframework.jdbc.core.JdbcTemplate;

import java.util.Date;
public class EmployeeService {
    private EmployeeDao employeeDao;
    private JdbcTemplate jdbcTemplate;

    public JdbcTemplate getJdbcTemplate() {
        return jdbcTemplate;
    }

    public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }

    public EmployeeDao getEmployeeDao() {
        return employeeDao;
    }
    public void setEmployeeDao(EmployeeDao employeeDao) {
        this.employeeDao = employeeDao;
    }

    public void batchImport(){
        for(int i=1;i<10;i++){
            Employee employee= new Employee();
            if(2==i){
                throw new RuntimeException("异常错误");
            }
            employee.setEno(i);
            employee.setEname("研发人员"+i);
            employee.setSalary(900f);
            employee.setDname("研发部");
            employee.setHiredate(new Date());
            employeeDao.insert(employee);
        }
    }
}

5.接下来我们写一下测试类

//获取对应的测试单元
@RunWith(SpringJUnit4ClassRunner.class)
//引入对应的配置文件
@ContextConfiguration(locations = {"classpath:applicationContext.xml"})
public class JdbcTemplateTestor {
    //批量写入数据
    @Resource
    //注入对象
    private EmployeeService employeeService;
    @Test
    public void  testBatchImport(){
        employeeService.batchImport();

    }

}

通过控制台,我们看到报错信息 image.png 回到数据库,我们发现写入了一条数据,其他的异常被捕获的代码都没有执行进去了,这是没有使用事物导致的结果 image.png

6.开启事务处理

<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>

    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <tx:attributes>
        //这边定义method是为了说明那个方法支持事务
            <tx:method name="batchImport" propagation="REQUIRED"/>
<!--            <tx:method name="*" propagation="REQUIRED"/>-->
        </tx:attributes>
    </tx:advice>
    <aop:config>
    //定义切点以及作用范围
        <aop:pointcut id="pointCut" expression="execution(* com.imooc..*Service.*(..))"/>
        <aop:advisor advice-ref="txAdvice" pointcut-ref="pointCut"/>
    </aop:config>

开启事务执行的相关日志为,此时发现错误,事务直接回滚 image.png 如果没有发生异常,则直接提交事务 image.png