Spring事务主要分为编程式和声明式两大类,前者通过PlatformTransactionManager或TransactionTemplate在代码中手动控制事务,后者通过@Transactional注解结合AOP实现事务管理,具有低侵入性和高可维护性,是现代Spring应用的首选方式。

Spring事务的实现方式,说白了,主要就两大类:一种是编程式事务,另一种是声明式事务。在我个人的经验里,声明式事务因为其便捷性和低侵入性,几乎成了现代Spring应用的首选,但了解编程式事务的底层逻辑也绝不是坏事。
解决方案
Spring框架在事务管理上提供了强大的支持,核心在于抽象了底层事务API(如JDBC、JTA、JPA等),提供了一致的编程模型。
1. 编程式事务管理 这种方式需要你在代码中显式地调用事务API来管理事务的开始、提交和回滚。它提供了最细粒度的控制,但缺点是代码侵入性强,容易产生大量重复代码。
使用PlatformTransactionManager
PlatformTransactionManager
TransactionStatus
@Service
public class MyService {
    private final PlatformTransactionManager transactionManager;
    public MyService(PlatformTransactionManager transactionManager) {
        this.transactionManager = transactionManager;
    }
    public void doSomethingTransactional() {
        DefaultTransactionDefinition def = new DefaultTransactionDefinition();
        TransactionStatus status = transactionManager.getTransaction(def);
        try {
            // 业务逻辑操作
            // 例如:dao.insertDataA(); dao.updateDataB();
            transactionManager.commit(status);
        } catch (Exception e) {
            transactionManager.rollback(status);
            throw new RuntimeException("Transaction failed", e);
        }
    }
}使用TransactionTemplate
PlatformTransactionManager
@Service
public class MyService {
    private final TransactionTemplate transactionTemplate;
    public MyService(PlatformTransactionManager transactionManager) {
        this.transactionTemplate = new TransactionTemplate(transactionManager);
    }
    public void doSomethingTransactionalWithTemplate() {
        transactionTemplate.execute(status -> {
            try {
                // 业务逻辑操作
                // 例如:dao.insertDataC(); dao.deleteDataD();
                return "Success";
            } catch (Exception e) {
                status.setRollbackOnly(); // 标记事务为回滚
                throw new RuntimeException("Transaction failed", e);
            }
        });
    }
}2. 声明式事务管理 这是Spring推荐的方式,通过AOP(面向切面编程)实现。你不需要在业务代码中显式编写事务管理逻辑,只需通过配置(XML或注解)来声明哪些方法需要事务支持。Spring会在运行时通过代理为这些方法织入事务管理功能。
基于XML配置: 早期项目或一些特定场景下可能会用到。通过
<tx:advice>
<aop:config>
基于@Transactional
@Transactional
当你在方法上加上
@Transactional
RuntimeException
Error
propagation
REQUIRED
REQUIRES_NEW
isolation
READ_COMMITTED
REPEATABLE_READ
timeout
readOnly
rollbackFor
noRollbackFor
@Service
public class UserService {
    // 假设有用户数据访问对象
    // private final UserRepository userRepository;
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void createUserAndAssignRole(User user, Role role) {
        // userRepository.save(user);
        // roleRepository.assign(user.getId(), role.getId());
        // 如果这里有任何异常,整个方法的操作都会回滚
    }
    @Transactional(readOnly = true)
    public User getUserById(Long id) {
        // return userRepository.findById(id);
        return null;
    }
}在我看来,
@Transactional
Spring事务的传播行为有哪些,如何理解?
事务传播行为,这玩意儿听起来有点玄乎,但其实就是当一个方法调用另一个方法时,这两个方法的事务如何相互作用的规则。理解这些规则,对于避免一些难以察觉的事务问题至关重要。Spring定义了七种传播行为,但日常开发中常用的也就那么几种。
REQUIRED
SUPPORTS
MANDATORY
REQUIRES_NEW
NOT_SUPPORTED
NEVER
NOT_SUPPORTED
NESTED
REQUIRED
REQUIRES_NEW
为什么我的Spring事务不生效?常见陷阱与排查。
说实话,
@Transactional
方法不是public
public
@Transactional
private
protected
public
同一个类中方法A调用方法B(自调用问题): 这是一个非常经典的陷阱。当你在同一个Service类中,一个没有
@Transactional
@Transactional
原因: Spring的事务是通过代理实现的。当你通过
this
排查:
@Service
public class MyService {
    @Transactional // 这个事务不会生效
    public void methodB() {
        System.out.println("Method B executed.");
        // ... 业务逻辑 ...
    }
    public void methodA() {
        System.out.println("Method A executed.");
        this.methodB(); // 直接通过this调用,绕过了代理
    }
}解决方案:
methodB
AopContext.currentProxy()
((MyService) AopContext.currentProxy()).methodB();
exposeProxy = true
异常类型不对,或者异常被捕获了: 默认情况下,Spring事务只对运行时异常(
RuntimeException
Error
IOException
SQLException
@Transactional(rollbackFor = MyCheckedException.class)
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
数据库不支持事务: 某些数据库存储引擎(比如MySQL的MyISAM)是不支持事务的。虽然Spring的事务配置没问题,但底层数据库不支持,自然也就无法实现事务。
没有启用Spring的事务管理: 忘记在Spring配置中启用事务管理,比如没有
@EnableTransactionManagement
<tx:annotation-driven/>
事务方法内部调用了非事务方法,且非事务方法抛出了异常: 如果一个事务方法内部调用了一个没有
@Transactional
编程式事务与声明式事务,我该如何选择?
这其实是一个经典的取舍问题,但现代应用开发中,答案往往偏向一边。
在我看来,绝大多数情况下,你应该选择声明式事务,特别是基于@Transactional
那么,什么时候会考虑编程式事务呢? 说实话,这种情况非常少见,但也不是没有。
Connection
总的来说,如果你正在开发一个新的Spring应用,或者对现有应用进行现代化改造,请毫不犹豫地拥抱
@Transactional
以上就是spring 事务实现方式有哪些?的详细内容,更多请关注php中文网其它相关文章!
 
                        
                        每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
 
                Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号