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();

            }
        }
    } );
}
相关推荐
my一阁26 分钟前
2025-web集群-问题总结
前端·arm开发·数据库·nginx·负载均衡·web
JIngJaneIL2 小时前
篮球论坛|基于SprinBoot+vue的篮球论坛系统(源码+数据库+文档)
java·前端·数据库·vue.js·论文·毕设·篮球论坛系统
一只叫煤球的猫4 小时前
MySQL 索引的 “最左前缀原则”,用查字典的例子讲透
数据库·mysql·性能优化
一只小bit5 小时前
MySQL常用内置函数整理:提高你的查询效率
数据库·mysql·数据完整性·表约束
朝新_6 小时前
【SpringBoot】详解Maven的操作与配置
java·spring boot·笔记·后端·spring·maven·javaee
数字化顾问6 小时前
SQL之键与约束实战进阶——从基础语法到高并发场景优化
sql
chxii6 小时前
ISO 8601日期时间标准及其在JavaScript、SQLite与MySQL中的应用解析
开发语言·javascript·数据库
小丁爱养花8 小时前
Redis 内部编码/单线程模型/string
数据库·redis·缓存·1024程序员节