[学习记录]Spring事务管理器TransactionTemplate -- 手动方式 经典案例“转账”

数据库

简单的两个字段,一个用户,一个金额
在这里插入图片描述

Idea

- dao层

  • 首先分析转账涉及到的数据:汇款方(outer)、收款方(inner)、转账金额(money)

  • 所以dao层有两个对象:

  • 汇款方(谁汇款、汇多少钱) → outer(outerName,money)

  • 收款方(谁收款,收多少钱) → inner(innerName,money)

  • 因为dao层跟JDBC模板挂钩,所以会用到一个类 --> JdbcDaoSupport(该类可获得JdbcTemplate,同时需在XML文件里将dataSource注入进JdbcTemplate)

*参考代码(接口)*
public interface UserDao {
    public void in(String inner,int money);

    public void out(String outer,int money);
}

因为此处继承了JdbcDaoSupport ,所以可以直接获得Jdbc的模板 JdbcTemplate

*参考代码(接口实现类)*
public class UserDaoImpl extends JdbcDaoSupport implements UserDao {
    @Override
    public void in(String inner, int money) {
        this.getJdbcTemplate().update("update t_account_lv set money = money + ? where user = ?",money,inner);
    }

    @Override
    public void out(String outer, int money) {
        this.getJdbcTemplate().update("update t_account_lv set money = money - ? where user = ?",money,outer);
    }
}

service层

-service层可以简单的理解成转账操作(transfer),通过service层调用dao层的数据,从而完成转账。

-所以service层里就一个转账的方法:transfer(inner,outer,money)

-然后将dao层里的数据注入到service层里,提供一个set方法

	private UserDao userDao;
	
    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }

配置XML文件
首先肯定是要用到service,但是service需要有dao,dao又需要有DataSource

所以

第一步:配置数据源(即数据库连接的一些列操作)

<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
        <property name="url" value="jdbc:mysql://localhost:3306/db_account_lv?characterEncoding=UTF-8"></property>
        <property name="username" value="root"></property>
        <property name="password" value="root"></property>
</bean>

第二步:配置dao

   <bean id="userDao" class="NulLV.dao.UserDaoImpl">
        <property name="dataSource" ref="dataSource"></property>
    </bean>

第三步:配置service

<bean id="accountService" class="NulLV.service.AccountServiceImpl">
        <property name="userDao" ref="userDao"></property>
        <property name="transactionTemplate" ref="transactionTemplate"></property>
</bean>

完成上述后便可以简单的测试一下转账操作了

测试类

public class TransferTest {
    public static void main(String[] args) {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-config.xml");

        AccountService accountService = (AccountService) applicationContext.getBean("accountService");

        accountService.transfer("威威","威威猫",1000);

    }
}

实施效果
可以看到威威猫给威威转了1000块钱
在这里插入图片描述

然后我们在转账的过程中人为的添加一个错误后再运行,发现汇款方钱减少了,但是收款方却没有收到钱,这种现象是不符合日常规律的,所以就需要用到我们的事务管理器。
在这里插入图片描述
这里两个字段写反了,见谅,哈哈在这里插入图片描述

- 简单理解一下事务管理器:

假如我按执行一系列操作,我执行到了一半,发生了异常,但是之前完成的操作导致一些数据发生了变更,这个时候因为有了事务管理器,这些发生变更的数据会因为事务管理器回调到没变更时的样子。

使用事务管理器

  • 首先Spring底层是使用TransactionTemplate事务模板进行操作的

  • (重点)转账方法在service里进行,所以需要将TransactionTemplate模板放到service里去(这里就要去XML里配置模板,并且注入到service里去)

  • (重点)但是此时还只是一个模板,模板想要真正管理事务(这里的事务即转账),就得用到事务管理器(DataSourceTransactionManager)才能进行管理。

  • (重点)要用到事务管理器,也得在XML文件里进行配置和注入(跟使用service就得配置dao,要得到dao又需要配置DataSource同理,一环扣一环)

    ——————————————有了思路我们就开始进行注入和配置——————————————

第一步:
在service里注入模板,并提供set方法得到模板

	private TransactionTemplate transactionTemplate;

    public void setTransactionTemplate(TransactionTemplate transactionTemplate) {
        this.transactionTemplate = transactionTemplate;
    }

第二步:

  • 使用transactionTemplate的execute方法里的TransactionCallbackWithoutResult()回调函数

在这里插入图片描述

  • 该回调函数里又包含了一个方法:

protected void doInTransactionWithoutResult(TransactionStatus transactionStatus)()

我们要做的就是将转账的操作放到上述的方法里,因为是匿名内部类的方式,需要给参数添加final修饰

    @Override
    public void transfer(final String inner,final String outer,final int money) {
            transactionTemplate.execute(new TransactionCallbackWithoutResult() {
                @Override
                protected void doInTransactionWithoutResult(TransactionStatus transactionStatus) {
                    userDao.in(inner, money);
                    //        int i = 1/0;
                    userDao.out(outer, money);
                }
            });
    }

第三步:
在XML文件中配置模板和事务管理器

- 首先service需要用到模板,先把模板注入到service里
在这里插入图片描述

- 此时还没有模板,所以需要创建模板
在这里插入图片描述

- 然后之前提到模板还没有真正管理事务,所以需要配置事务管理器并注入到模板中
事务管理器的名字一般都叫做txManager(理解成约定俗成的就行)
事务管理器需要事务,此时事务就需要从Connection获得,而连接则是从数据源DataSource获得
在这里插入图片描述

测试对比

可以发现尽管出现了错误异常,但是数据库中的数据还是没有发生变化
在这里插入图片描述

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值