Spring 事务

Spring对事务的管理

1.Spring管理事务的接口

  • 事务管理器接口(PlatformTransactionManager)
  • 事务定义接口(TransactionDefinition)

2.事务管理的实现方式

  • 通过配置xml实现事务的管理
  • 利用注解实现事务的管理

下面用一个转账实例通过配置xml实现事务的管理,助于理解

项目目录

  • dao层负责与数据库进行交互。dao层通常包含接口(interface),这些接口定义了与数据库交互的方法,例如增加、删除、修改和查询等等操作。
  • impl(implementation缩写)软件包,通常用来放置这些接口的实现类。

这样的结构带来的好处:

  1. 分离接口和实现:这是一种常见的软件设计模式,称为接口分离原则。通过将接口与实现分离,可以提供更清晰的职责划分,并允许接口在不同实现之间的重用。
  2. 易于维护和扩展:如果将来需要更改数据访问的实现方式(例如,从JDBC切换到JPA或MyBatis),只需要在impl包中更改或添加新的实现类,而不需要修改接口或使用这些接口的代码。
  3. 便于测试:接口允许开发者编写更易于测试的代码。通过使用接口,可以在单元测试中轻松地替换真实的数据库实现类。
  4. 降低不同层之间的耦合度

数据库表格:

AliDaoImpl文件:

import com.qcby.dao.AlipayDao;
import org.springframework.jdbc.core.JdbcTemplate;

public class AlipayDaoImpl implements AlipayDao {




    @Override
    public void transfer(String fromA, String toB, Double money) {
        jdbcTemplate.update("update affair set money = money-? where  name = ? ",money,fromA);
        //Integer a = Integer.valueOf("你好");
        jdbcTemplate.update("update affair set money = money+? where  name = ? ",money,toB);
    }


    /*
    * 让A给B转账100
    * @Param fromA
    * @Param toB
    * @param money
    * */

    private JdbcTemplate jdbcTemplate;

    public JdbcTemplate getJdbcTemplate(){
        return jdbcTemplate;
    }

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

}

dao接口(AlipayDao):

定义了方法

public interface AlipayDao {
    public void transfer(String fromA,String toB,Double money);
}

实体层entity(Alipay):

封装属性并生成get、set和tostring()方法

public class Alipay {
    private String name;
    private Double money;

    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 "Alipay{" +
                "name='" + name + '\'' +
                ", money=" + money +
                '}';
    }
}

测试类:

 public static void main(String[] args) {
           ApplicationContext applicationContext = new  ClassPathXmlApplicationContext("Application.xml");
           AlipayDao alipayDao = (AlipayDao) applicationContext.getBean("AlipayDaoImpl");
           alipayDao.transfer("张三","李四",50.00);
       }

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:tx="http://www.springframework.org/schema/tx"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/tx https://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
    
<!--    配置连接DriverManagerDataSource-->
    <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/mybatis_demo"/>
        <property name="username" value="root"/>
        <property name="password" value="2020"/>
    </bean>

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

    <bean id="AlipayDaoImpl" class="com.qcby.dao.impl.AlipayDaoImpl">
        <property name="jdbcTemplate" ref="jdbcTemplate"/>
    </bean>
<!--定义事务管理器-->
    <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>
<!--编写事务的通知-->
  <!--  method标识匹配的切点方法都进行事务管理,这里*表示匹配的所有的切点方法,propagation="REQUIRED"表示匹配的切点方法必须在事务内执行。
    isolation="DEFAULT"表示事务隔离级别默认,对于MySQL数据库,隔离级别为REPEATABLE_READ(可重复读),read-only="false"表示非只读。-->
    <tx:advice id="txTransaction" transaction-manager="txManager">
        <tx:attributes>
            <tx:method name="*" propagation="REQUIRED" isolation="DEFAULT" read-only="false"/>
        </tx:attributes>
    </tx:advice>
<!--    将配置好的事务放到切入点当中-->
    <aop:config>
        <!--定义出切入点-->
        <aop:pointcut id="transfer" expression="execution(* com.qcby.dao.impl.AlipayDaoImpl.transfer(..))"/>
<!--        将事务和切入点组合-->
        <aop:advisor advice-ref="txTransaction" pointcut-ref="transfer"/>
    </aop:config>
</beans>

通知有五种(见小编Spring AOP一文)放到这边都不适用,因为我们这里需要将事务和通知放在一起。

正常情况下的运行结果(在AlipayDaoImpl中注释掉Integer a = Integer.valueOf("你好");这个人为设置的报错):

数据库结果:

张三变成了50,李四变成了150

如果人为加上错误

最后运行结果:

人为设置错误,数据库没有改变,证实了事务的特性,其中一旦有错,两条语句都不执行。

  • 14
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值