当前位置: 代码网 > it编程>编程语言>Java > SpringBoot 编程式事务使用及两种实现方式

SpringBoot 编程式事务使用及两种实现方式

2024年12月21日 Java 我要评论
1. 简介编程式事务管理是通过编写代码来管理事务,相对于声明式事务(@transactional注解),它提供了更细粒度的事务控制。在 springboot 中,主要有两种实现方式:使用 transa

1. 简介

编程式事务管理是通过编写代码来管理事务,相对于声明式事务(@transactional注解),它提供了更细粒度的事务控制。在 springboot 中,主要有两种实现方式:

  • 使用 transactiontemplate
  • 直接使用 transactionmanager

2. transactiontemplate 方式

transactiontemplate 是最简单的编程式事务实现方式,它对底层事务 api 进行了封装,使用起来更加便捷。

2.1 基本配置

@configuration
public class transactionconfig {
    @autowired
    private platformtransactionmanager transactionmanager;
    @bean
    public transactiontemplate transactiontemplate() {
        transactiontemplate template = new transactiontemplate();
        template.settransactionmanager(transactionmanager);
        // 设置默认的事务传播行为
        template.setpropagationbehavior(transactiondefinition.propagation_required);
        // 设置默认的事务隔离级别
        template.setisolationlevel(transactiondefinition.isolation_default);
        // 设置默认超时时间
        template.settimeout(30);
        return template;
    }
}

2.2 基本使用示例

@service
@slf4j
public class userservice {
    @autowired
    private transactiontemplate transactiontemplate;
    @autowired
    private userrepository userrepository;
    public user createuser(user user) {
        // 使用 execute 方法执行有返回值的事务操作
        return transactiontemplate.execute(status -> {
            try {
                user saveduser = userrepository.save(user);
                // 模拟其他操作
                updateuserprofile(saveduser);
                return saveduser;
            } catch (exception e) {
                // 手动标记事务回滚
                status.setrollbackonly();
                log.error("创建用户失败", e);
                throw new runtimeexception("创建用户失败", e);
            }
        });
    }
    public void batchcreateusers(list<user> users) {
        // 使用 executewithoutresult 方法执行无返回值的事务操作
        transactiontemplate.executewithoutresult(status -> {
            try {
                for (user user : users) {
                    userrepository.save(user);
                }
            } catch (exception e) {
                status.setrollbackonly();
                log.error("批量创建用户失败", e);
                throw new runtimeexception("批量创建用户失败", e);
            }
        });
    }
}

3. transactionmanager 方式

直接使用 transactionmanager 提供了更细粒度的事务控制,但使用起来相对复杂。

3.1 基本使用示例

@service
@slf4j
public class orderservice {
    @autowired
    private platformtransactionmanager transactionmanager;
    @autowired
    private orderrepository orderrepository;
    public order createorder(order order) {
        // 定义事务属性
        defaulttransactiondefinition def = new defaulttransactiondefinition();
        def.setpropagationbehavior(transactiondefinition.propagation_required);
        def.setisolationlevel(transactiondefinition.isolation_read_committed);
        def.settimeout(30);
        // 获取事务状态
        transactionstatus status = transactionmanager.gettransaction(def);
        try {
            // 执行业务逻辑
            order savedorder = orderrepository.save(order);
            // 处理订单相关的其他操作
            processorderdetails(savedorder);
            // 提交事务
            transactionmanager.commit(status);
            return savedorder;
        } catch (exception e) {
            // 回滚事务
            transactionmanager.rollback(status);
            log.error("创建订单失败", e);
            throw new runtimeexception("创建订单失败", e);
        }
    }
}

3.2 嵌套事务示例

@service
@slf4j
public class paymentservice {
    @autowired
    private platformtransactionmanager transactionmanager;
    @autowired
    private paymentrepository paymentrepository;
    public void processpayment(payment payment) {
        // 外部事务定义
        defaulttransactiondefinition outerdef = new defaulttransactiondefinition();
        outerdef.setpropagationbehavior(transactiondefinition.propagation_required);
        transactionstatus outerstatus = transactionmanager.gettransaction(outerdef);
        try {
            // 外部事务操作
            paymentrepository.save(payment);
            // 内部事务定义
            defaulttransactiondefinition innerdef = new defaulttransactiondefinition();
            innerdef.setpropagationbehavior(transactiondefinition.propagation_nested);
            transactionstatus innerstatus = transactionmanager.gettransaction(innerdef);
            try {
                // 执行内部事务操作
                processpaymentdetails(payment);
                transactionmanager.commit(innerstatus);
            } catch (exception e) {
                // 回滚内部事务
                transactionmanager.rollback(innerstatus);
                log.error("支付详情处理失败", e);
                throw e;
            }
            // 提交外部事务
            transactionmanager.commit(outerstatus);
        } catch (exception e) {
            // 回滚外部事务
            transactionmanager.rollback(outerstatus);
            log.error("支付处理失败", e);
            throw new runtimeexception("支付处理失败", e);
        }
    }
}

4. 事务传播行为

在编程式事务中,我们可以精确控制事务的传播行为:

@service
public class transactionpropagationexample {
    @autowired
    private transactiontemplate transactiontemplate;
    public void demonstratepropagation() {
        // required 传播行为
        transactiontemplate requiredtemplate = new transactiontemplate(transactiontemplate);
        requiredtemplate.setpropagationbehavior(transactiondefinition.propagation_required);
        // requires_new 传播行为
        transactiontemplate requiresnewtemplate = new transactiontemplate(transactiontemplate);
        requiresnewtemplate.setpropagationbehavior(transactiondefinition.propagation_requires_new);
        // 嵌套使用不同的传播行为
        requiredtemplate.execute(outerstatus -> {
            // 外部事务逻辑
            requiresnewtemplate.execute(innerstatus -> {
                // 内部事务逻辑(新的事务)
                return null;
            });
            return null;
        });
    }
}

5. 事务隔离级别

示例展示如何设置不同的事务隔离级别:

@service
public class transactionisolationexample {
    @autowired
    private platformtransactionmanager transactionmanager;
    public void demonstrateisolation() {
        // 读已提交隔离级别
        defaulttransactiondefinition readcommitteddef = new defaulttransactiondefinition();
        readcommitteddef.setisolationlevel(transactiondefinition.isolation_read_committed);
        transactionstatus readcommittedstatus = transactionmanager.gettransaction(readcommitteddef);
        try {
            // 业务逻辑
            transactionmanager.commit(readcommittedstatus);
        } catch (exception e) {
            transactionmanager.rollback(readcommittedstatus);
            throw e;
        }
        // 可重复读隔离级别
        defaulttransactiondefinition repeatablereaddef = new defaulttransactiondefinition();
        repeatablereaddef.setisolationlevel(transactiondefinition.isolation_repeatable_read);
        // ... 类似的事务处理逻辑
    }
}

6. 最佳实践

6.1 事务模板封装

创建一个通用的事务处理模板:

@component
@slf4j
public class transactionhelper {
    @autowired
    private transactiontemplate transactiontemplate;
    public <t> t executeintransaction(transactioncallback<t> action) {
        try {
            return transactiontemplate.execute(action);
        } catch (exception e) {
            log.error("事务执行失败", e);
            throw new runtimeexception("事务执行失败", e);
        }
    }
    public void executeintransactionwithoutresult(consumer<transactionstatus> action) {
        try {
            transactiontemplate.executewithoutresult(action);
        } catch (exception e) {
            log.error("事务执行失败", e);
            throw new runtimeexception("事务执行失败", e);
        }
    }
}
// 使用示例
@service
public class businessservice {
    @autowired
    private transactionhelper transactionhelper;
    public void dobusiness() {
        transactionhelper.executeintransactionwithoutresult(status -> {
            // 业务逻辑
        });
    }
}

7. 常见问题与解决方案

7.1 事务超时处理

@service
public class timeoutexample {
    @autowired
    private transactiontemplate transactiontemplate;
    public void handletimeout() {
        transactiontemplate timeouttemplate = new transactiontemplate(transactiontemplate);
        timeouttemplate.settimeout(5); // 设置5秒超时
        try {
            timeouttemplate.execute(status -> {
                // 可能超时的业务逻辑
                return null;
            });
        } catch (transactiontimedoutexception e) {
            // 处理超时异常
            log.error("事务执行超时", e);
            throw new runtimeexception("事务执行超时", e);
        }
    }
}

7.2 异常处理最佳实践

@service
public class exceptionhandlingexample {
    @autowired
    private transactiontemplate transactiontemplate;
    public void handleexceptions() {
        try {
            transactiontemplate.execute(status -> {
                try {
                    // 业务逻辑
                    return null;
                } catch (businessexception e) {
                    // 业务异常,标记回滚
                    status.setrollbackonly();
                    throw e;
                } catch (exception e) {
                    // 其他异常,标记回滚
                    status.setrollbackonly();
                    throw new runtimeexception("未预期的错误", e);
                }
            });
        } catch (exception e) {
            // 统一异常处理
            handleexception(e);
        }
    }
    private void handleexception(exception e) {
        if (e instanceof businessexception) {
            // 处理业务异常
            log.warn("业务异常: {}", e.getmessage());
        } else {
            // 处理系统异常
            log.error("系统异常", e);
        }
        throw e;
    }
}

虽然编程式事务提供了更细粒度的控制,但在大多数情况下,声明式事务(@transactional)可能是更好的选择。只有在需要特别精细的事务控制时,才考虑使用编程式事务。

到此这篇关于springboot 编程式事务使用的文章就介绍到这了,更多相关springboot 编程式事务内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com