Spring——编程式事务

目录

platformtransactionManager

TransactionDefinition

TransactionStatus

编程式事务

PlatformTransactionManager手动管理事务

TransactionTemplate管理事务


platformtransactionManager

platformtransactionManager是**spring处理事务的核心接口,**为不同的事务管理实现提供了一个统一的编程模型。Spring本身不管理事务,而是通过这个接口适配各种底层的事务机制。该接口有3个方法。

java 复制代码
public interface PlatformTransactionManager {

    // 获取一个事务(根据定义创建或加入已有事务)
    TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException;

    // 提交事务
    void commit(TransactionStatus status) throws TransactionException;

    // 回滚事务
    void rollback(TransactionStatus status) throws TransactionException;
}

核心方法说明:

  • getTransaction(TransactionDefinition definition)

    • 根据事务定义(传播行为、隔离级别、超时等)获取一个事务。
    • 如果当前线程已有事务,根据传播行为决定是加入还是新建。
    • 返回 TransactionStatus 对象,表示当前事务状态。
  • commit(TransactionStatus status)

    • 提交事务。
    • 如果事务已标记为 rollback-only,则执行回滚。
  • rollback(TransactionStatus status)

    • 回滚事务。

TransactionDefinition

TransactionDefinition用于定义事务的属性,描述事务的边界和行为规则。

主要内容:

  • 传播行为(Propagation)

    • REQUIRED(默认):如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务

    • REQUIRES_NEW:创建一个新的事务,如果当前存在事务,则把当前事务挂起

    • NESTED:如果当前存在事务,则创建一个事务作为当前事务的嵌套事务;如果当前没有事务,则等价于REQUIRED

    • SUPPORTS:如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务的方式继续运行

    • NOT_SUPPORTED:以非事务方式运行,如果当前存在事务,则把当前事务挂起

    • NEVER:以非事务方式运行,如果当前存在事务,则抛出异常

    • MANDATORY:如果当前存在事务,则加入该事务;如果当前没有事务,则抛出异常

  • 隔离级别(Isolation)

    • DEFAULT:使用底层数据库的默认隔离级别

    • READ_UNCOMMITTED:读未提交

    • READ_COMMITTED:读已提交

    • REPEATABLE_READ:可重复读

    • SERIALIZABLE:串行化

  • 超时时间(Timeout)

  • 是否只读(Read-only)

TransactionStatus

TransactionStatus接口表示事务的状态,用于在事务的执行过程中查询状态和控制事务。

java 复制代码
public interface TransactionStatus extends SavepointManager {
    
    // 判断是否是新的事务
    boolean isNewTransaction();
    
    // 判断是否有保存点
    boolean hasSavepoint();
    
    // 设置事务为只回滚
    void setRollbackOnly();
    
    // 判断事务是否已被标记为只回滚
    boolean isRollbackOnly();
    
    // 判断事务是否已完成
    boolean isCompleted();
}

编程式事务

编程式事务可以在代码中显示的调用事务管理API来控制事务边界。

PlatformTransactionManager手动管理事务

首先在spring的配置文件中提供一个事务管理器:

XML 复制代码
<bean class="org.springframework.transaction.support.TransactionTemplate" id="transactionTemplate">
        <property name="transactionManager" ref="transactionManager"/>
</bean>

然后注入到service层,并且编写对应的方法,这里使用ORM的是mybatis:

java 复制代码
public class UserService {

    @Autowired
    PlatformTransactionManager platformTransactionManager;
    @Autowired
    UserDao userDao;

    public void trans(){
        //1.定义默认的事务属性
        DefaultTransactionDefinition definition = new DefaultTransactionDefinition();
        //2.获取TransactionStatus
        TransactionStatus transaction = platformTransactionManager.getTransaction(definition);
        try{
            userDao.updateUsernameById(1,"6k");
            platformTransactionManager.commit(transaction);
        }catch (Exception e){
            platformTransactionManager.rollback(transaction);

        }
    }
}

运行启动调用这个方法之后发现确实修改成功了,看起来加没加事务没有什么区别。接下来在后面抛个异常:

发现即使已经调用了接口中的方法,数据依旧没有修改,说明这个事务被回滚了!

TransactionTemplate管理事务

依旧在spring配置文件中提供事务管理器./

XML 复制代码
<bean class="org.springframework.transaction.support.TransactionTemplate" id="transactionTemplate">
        <property name="transactionManager" ref="transactionManager"/>
</bean>

注入TransactionTemplate

java 复制代码
@Autowired
TransactionTemplate transactionTemplate;
java 复制代码
/**
 * 基于TransactionTemplate的编程式事务方法(trans2)
 * 说明:TransactionTemplate是Spring提供的事务模板类,简化了编程式事务的代码(无需手动commit/rollback)
 */
public void trans2(){
    // 调用TransactionTemplate的execute方法,传入事务回调接口(TransactionCallbackWithoutResult)
    transactionTemplate.execute(new TransactionCallbackWithoutResult() {
        
        // 重写回调接口的doInTransactionWithoutResult方法
        // 作用:该方法内的代码会运行在事务环境中,TransactionStatus参数用于控制事务状态(如标记回滚)
        @Override
        protected void doInTransactionWithoutResult(TransactionStatus status) {
            try{
                // 说明:此操作会被Spring事务管理,若后续出现异常,该更新会被回滚
                userDao.updateUsernameById(1,"ojbk");
                int i = 1/0;
                
            }catch (Exception e){
                //  异常处理:当业务逻辑抛出异常时,手动标记事务为"需要回滚"
                status.setRollbackOnly();

            }
        }
    } );
}
相关推荐
梦影_6 分钟前
MySQL进阶教程(二)—— 储存过程与触发器(下)
开发语言·数据库·后端·sql·mysql·oracle·数据库开发
工业涂料百问10 分钟前
陶瓷涂料的光泽度怎么检测?20°、60°、85° 三个角度怎么选
数据库
科创致远19 分钟前
ESOP 电子作业指导书车间无纸化实战评测
大数据·数据库·人工智能·制造
xiaomuzuirenzhen24 分钟前
2027车企数字化岗位项目准备:从SQL数据建模到库存分析看板
大数据·数据库·sql
鸽芷咕28 分钟前
从环境搭建到敬礼动作:启元 Q1 SDK 全流程实战与 8 个实测坑排查手册
数据库·ai·机器人·sdk·启元q1
步行cgn30 分钟前
Spring MVC POST 请求乱码:原因与完整解决方案
java·spring·mvc
科技研学社36 分钟前
服装厂激光开袋机与智能模板机怎么选?核心工序设备深度对比与落地实战
数据库·python
其实防守也摸鱼2 小时前
Cylab在线靶场——挑战图书馆初学者指南
服务器·前端·数据库·chrome·安全·网络安全·靶场
运维行者_5 小时前
应用性能监控怎么选?从调用链到用户体验的五个能力维度
运维·服务器·数据库·人工智能·mysql·性能优化·应用性能监控