当前位置 > it书童 > java > 正文
推荐小册
java高效编程
怎样更高效地用 java 编程

juc并发工具库
java并发编程工具库

设计模式
设计模式

jvm调优
jvm调优

rabbitmq实战
rabbitmq实战

redis实战
redis实战

Keepavlied高可用集群
Keepavlied高可用集群

nginx入门到实战
nginx入门到实战

java调试
java调试中遇到的各种坑

java输入输出流
java输入输出流

spring 使用事务实现转账小案例

java it书童 2020-08-20 17:53:13 0赞 0踩 656阅读 0评论

本文用又臭又长的纯手工 xml 配置事务,实现转账功能,代码很臃肿,仅供学习参考,实际项目肯定不会这么用,框架都为我们做好了。以下分析实现转账功能的几个注意点:

为了保证转账的正确性,必须让转账的所有 sql 操作都在同一个连接的事务中。但默认情况下,每次都是新建一个连接,每个连接都有自己的事务,如果中间程序出异常,就会导致结果不一致

事务控制

解决方案:将连接保存在同一线程上,保证每次执行 sql 用的都是同个连接,从而使用的是同一个事务

为了提高代码的复用性,不必在每个 sql 操作都写一大堆的事务代码,可以用动态代理的方式对相应方法进行增强,代码示例如下:

package com.itshutong.factory;

import com.itshutong.service.IAccountService;
import com.itshutong.utils.TransactionManager;
import lombok.Setter;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * 用于创建 Service 的代理对象的工厂类
 */
public class BeanFactory {

    @Setter
    private IAccountService accountService;

    @Setter
    private TransactionManager txManager;

    public IAccountService getAccountService() {
        return (IAccountService) Proxy.newProxyInstance(
            accountService.getClass().getClassLoader(),
            accountService.getClass().getInterfaces(),
            new InvocationHandler() {
                @Override
                public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                    Object rtValue = null;
                    try {
                        // 开启事务
                        txManager.beginTransaction();
                        // 执行操作
                        rtValue = method.invoke(accountService, args);
                        // 提交事务
                        txManager.commit();
                        // 返回结果
                        return rtValue;
                    } catch (Exception e) {
                        // 回滚操作
                        txManager.rollback();
                        throw new RuntimeException(e);
                    } finally {
                        txManager.release();
                    }
                }
            }
        );
    }
}

为了实现一个很简单的功能,要写一大堆代码,其实真正起作用的业务代码只有几行而已。当然,实际项目开发是不会这么弄的,这只是演示流程,框架都会为我们完成这些操作,否则开发工作就太枯燥了

源码 javaDemo 9085c7b

关于我
一个文科出身的程序员,追求做个有趣的人,传播有价值的知识,微信公众号主要分享读书思考心得,不会有代码类文章,非程序员的同学请放心订阅
转载须注明出处:https://www.itshutong.com/articles/650/spring-uses-transaction-to-realize-transfer