Spring——jdbcTemplate和声明式事务管理

简介:jdbcTemplate连接数据库和维护数据库数据操作原子性的声明式事务管理。

核心code:

xml法:

复制代码
    <!--    配置事务  XML方式-->

    <!--    事务管理器-->
        <bean id="transactionManager"
              class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
            <property name="dataSource" ref="dataSource"></property>
        </bean>
    <!--    配置事务管理器,Spring内置 -->
        <tx:advice id="txAdvice" transaction-manager="transactionManager">
            <tx:attributes>
                <tx:method name="transfer*" isolation="DEFAULT" propagation="REQUIRED"/>
            </tx:attributes>
        </tx:advice>

    <!--    配置切面-->
        <aop:config>
            <aop:advisor advice-ref="txAdvice"
                         pointcut="execution(* *..*.BankService.transfer*(..))"></aop:advisor>
        </aop:config>
appcontext.xml添加
复制代码

注解法:

    @Transactional(readOnly = false,
            propagation = Propagation.REQUIRES_NEW,
            isolation = Isolation.READ_COMMITTED)
事务方法头部添加注解
复制代码
    <!--    配置事务  注解方式-->
    <bean id="transactionManager"
          class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"></property>
    </bean>
    <!--    开启事务注解扫描-->
    <tx:annotation-driven transaction-manager="transactionManager"/>
appcontext.xml添加
复制代码

全部code:

pom.xml配置

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>ssm_spring</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>

    <dependencies>
        <!--        核心容器(core container)-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>5.3.10</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
            <version>5.3.10</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.3.10</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
            <version>5.3.10</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-expression</artifactId>
            <version>5.3.10</version>
        </dependency>
        <!--        AOP、aspects、spring-instrument 、messaging-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
            <version>5.3.10</version>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjrt</artifactId>
            <version>1.9.7</version>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.9.7</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aspects</artifactId>
            <version>5.3.10</version>
        </dependency>
        <!--        Data Access/Intergration-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>5.3.10</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
            <version>5.3.10</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-orm</artifactId>
            <version>5.3.10</version>
        </dependency>
        <!--        web-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>5.3.10</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.3.10</version>
        </dependency>
        <!-- 日志相关jar包 (可选)-->
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>compile</scope>
        </dependency>

        <!--        jdbcTemplate-->
        <dependency>
            <groupId>commons-dbcp</groupId>
            <artifactId>commons-dbcp</artifactId>
            <version>1.4</version>
        </dependency>
        <dependency>
            <groupId>commons-pool</groupId>
            <artifactId>commons-pool</artifactId>
            <version>1.6</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.47</version>
        </dependency>
    </dependencies>
</project>

resource内:

appContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<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:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop.xsd
        http://www.springframework.org/schema/tx
        http://www.springframework.org/schema/tx/spring-tx.xsd">

    <!--测试jdbcTemplate和事务管理-->

    <!--    配置数据源-->
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/ssm?useSSL=false&amp;characterEncoding=UTF-8"/>
        <property name="username" value="root"/>
        <property name="password" value="root"/>
    </bean>

    <!--        配置spring对象-->
    <bean id="bankDao" class="com.swpu.dao.BankDaoImpl">
        <property name="dataSource" ref="dataSource"></property>
    </bean>
    <bean id="bankService" class="com.swpu.service.BankServiceImpl">
        <property name="bankDao" ref="bankDao"></property>
    </bean>
    <bean id="bankController" class="com.swpu.controller.BankController">
        <property name="bankService" ref="bankService"></property>
    </bean>

    <!--    *********************注意文件头的引入********-->
    <!--    配置事务  XML方式-->

    <!--    事务管理器-->
    <!--    <bean id="transactionManager"-->
    <!--          class="org.springframework.jdbc.datasource.DataSourceTransactionManager">-->
    <!--        <property name="dataSource" ref="dataSource"></property>-->
    <!--    </bean>-->

    <!--    配置事务管理器,Spring内置 -->
    <!--    <tx:advice id="txAdvice" transaction-manager="transactionManager">-->
    <!--        <tx:attributes>-->
    <!--            <tx:method name="transfer*" isolation="DEFAULT" propagation="REQUIRED"/>-->
    <!--        </tx:attributes>-->
    <!--    </tx:advice>-->

    <!--    配置切面-->
    <!--    <aop:config>-->
    <!--        <aop:advisor advice-ref="txAdvice"-->
    <!--                     pointcut="execution(* *..*.BankService.transfer*(..))"></aop:advisor>-->
    <!--    </aop:config>-->


    <!--    配置事务  注解方式-->
    <bean id="transactionManager"
          class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"></property>
    </bean>
    <!--    开启事务注解扫描-->
    <tx:annotation-driven transaction-manager="transactionManager"/>
    <!--开启AOP注解扫描-->
    <bean id="transationAspect" class="com.swpu.aspectJ.TransationAspect"></bean>
    <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
    <!--        指定扫描包范围  这里不能写入,会与bean冲突-->
    <!--    <context:component-scan base-package="com.swpu"/>-->
</beans>
beans.xml

<?xml version="1.0" encoding="UTF-8"?>
<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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">

<!--    注解方式:构造注解方式同属性注解方式同-->
    <context:component-scan base-package="com.swpu"></context:component-scan>
</beans>

domain:

com.swpu.domain.Bank

package com.swpu.domain;

public class Bank {
    private Integer id;
    private String name;
    private double money;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public double getMoney() {
        return money;
    }

    public void setMoney(double money) {
        this.money = money;
    }

    @Override
    public String toString() {
        return "Bank{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", money=" + money +
                '}';
    }
}

dao:

BankDao

package com.swpu.dao;

public interface BankDao {
    //减钱
    void reduceMoney(String outName, double money);
    //加钱
    void increaseMoney(String inName, double money);
}
BankDaoImpl

package com.swpu.dao;

import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.support.JdbcDaoSupport;
import org.springframework.stereotype.Repository;

import javax.annotation.Resource;

@Repository
public class BankDaoImpl extends JdbcDaoSupport implements BankDao {
    
    public void reduceMoney(String outName, double money) {
        String sql = "update bank set money=money-? where name=?";
        this.getJdbcTemplate().update(sql, money, outName);
    }

    public void increaseMoney(String inName, double money) {
        String sql = "update bank set money=money+? where name=?";
        this.getJdbcTemplate().update(sql, money, inName);
    }
}

service:

BankService

package com.swpu.service;

public interface BankService {
    void transferMoney(String outName, String inName, double money);
}
BankServiceImpl

package com.swpu.service;

import com.swpu.dao.BankDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

@Service
public class BankServiceImpl implements BankService {
    private BankDao bankDao;

    public void setBankDao(BankDao bankDao) {
        this.bankDao = bankDao;
    }

    /**
     * 当转账过程中途出现错误,应当控制事务的回滚或提交
     *
     * @param outName
     * @param inName
     * @param money
     */
    @Transactional(readOnly = false,
            propagation = Propagation.REQUIRES_NEW,
            isolation = Isolation.READ_COMMITTED)
    public void transferMoney(String outName, String inName, double money) {
        bankDao.reduceMoney(outName, money);
        //在此处出错,若无设定事务,则减钱成功,加钱失败,不符合实际应用
//        System.out.println(1 / 0);
        //加钱
        bankDao.increaseMoney(inName, money);
    }
}

controller:

BankController

package com.swpu.controller;

import com.swpu.service.BankService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;

/**
 * 测试事务管理与jdbcTemplate
 */
@Controller
public class BankController {

    private BankService bankService;
    public void setBankService(BankService bankService) {
        this.bankService = bankService;
    }

    /**
     * 转账
     *
     * @param outName 转出账号
     * @param inName  转入账号
     * @param money   转账金额
     */
    public void transfer(String outName, String inName, double money) {
        bankService.transferMoney(outName, inName, money);
    }
}

Test:

BankTest

package com.swpu.test;

import com.swpu.controller.BankController;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class BankTest {

    @Test
    public void testJdbcTemplate(){
        ApplicationContext ac =
                new ClassPathXmlApplicationContext("appContext.xml");
        BankController bankController = (BankController) ac.getBean("bankController");
        bankController.transfer("name1","name2",100);
    }
}

aspectJ:

TransationAspect

package com.swpu.aspectJ;

import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;

@Aspect
public class TransationAspect {
    @Before(value = "execution(* *..*.*Service.trans*(..))")
    public void start(){
        System.out.println("开启事务管理");
    }
    @After(value ="execution(* *..*.*Service.trans*(..))")
    public void end(){
        System.out.println("结束事务管理");
    }
    @AfterThrowing(value = "execution(* *..*.*Service.trans*(..))")
    public void error(){
        System.out.println("事务异常!");
    }
}

【Over】

posted @   Renhr  阅读(50)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!
· 零经验选手,Compose 一天开发一款小游戏!
点击右上角即可分享
微信分享提示