Spring05——Spring 如何实现事务管理

在此之前,我们已经了解了 Spring 相关的基础知识,今天将为给位带来,有关 Spring 事务代理的相关知识。关注我的公众号「Java面典」,每天 10:24 和你一起了解更多 Java 相关知识点。

事务管理方式

在 Spring 项目中,我们可以用通过四种方式实现事务管理,分别是 编程式事务管理、基于 TransactionProxyFactoryBean的声明式事务管理、基于 @Transactional 的声明式事务管理 和 基于Aspectj AOP配置事务。其实现方式如下:

编程式事务管理

// JDBC 事务管理
Connection connection = DriverManager.getConnection("connUrl", "username", "password");
//关闭自动提交,此句代码会自动开启事务。默认为true,自动提交。
connection.setAutoCommit(false);  

String sql1 = "insert into user(name) values (?)";
PreparedStatement preparedStatement1 = connection.prepareStatement(sql1);
preparedStatement1.setString(1,"Java面典");
preparedStatement1.executeUpdate(); 

String sql2 = "update user set name=? where id=?";
PreparedStatement preparedStatement2 = connection.prepareStatement(sql2);
preparedStatement2.setString(1, "Java面典 new");
preparedStatement2.setInt(2, 10);
preparedStatement2.executeUpdate();  

try{
     //提交事务
    connection.commit();  
}catch (SQLException e){
    //失败就回滚
    connection.rollback();  
} finally {
    preparedStatement1.close();
    preparedStatement2.close();
    connection.close();
}

基于 TransactionProxyFactoryBean的声明式事务管理



    
    

基于 @Transactional 的声明式事务管理

@Service
public class UserServiceImpl implements IUserService {
    
    @Transactional(transactionManager = "transactionManager", rollbackFor = Exception.class)
    @Override
    public void add(User user) {
        // todo 
    }
}

基于Aspectj AOP配置事务



    

    

    
        
        
        
    

    

    
    
    

事务传播机制

Spring 的事务传播分为以下几个机制:

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

  • NOT_SUPPORTED:Spring 不为当前方法开启事务,相当于没有事务;

  • REQUIRES_NEW:不管是否存在事务,都创建一个新的事务,原来的方法挂起,新的方法执行完毕后,继续执行老的事务;

  • MANDATORY:必须在一个已有的事务中执行,否则报错;

  • NEVER:必须在一个没有的事务中执行,否则报错;

  • SUPPORTS:如果其他 bean 调用这个方法时,其他 bean 声明了事务,则就用这个事务,如果没有声明事务,那就不用事务;
    SUPPORTS类型的事务传播机制,是否使用事务取决于调用方法是否有事务,如果有则直接用,如果没有则不使用事务。

  • NESTED:如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与 REQUIRED 类似的操作;

注意事项

在 A 方法内,调用 B 方法时,存在以下规则:

  1. REQUIRED
    当两个方法的传播机制都是 REQUIRED 时,如果一旦发生回滚,两个方法都会回滚;
  2. REQUIRES_NEW
    当 A 方法传播机制为 REQUIRES_NEW ,会开启一个新的事务,并单独提交方法,所以 B 方法的回滚并不影响 A 方法事务提交;
  3. NESTED
    当 A 方法为 REQUIRED,B 方法为 NESTED 时,A 方法开启一个嵌套事务;
    当 A 方法回滚时,B 方法也会回滚;反之,如果 B 方法回滚,则并不影响 A 方法的提交。

事务隔离级别

TransactionDefinition 接口中定义了五个表示隔离级别的常量:

  • ISOLATION_DEFAULT:使用后端数据库默认的隔离界别,MySQL默认采用的REPEATABLE_READ 隔离级别,Oracle 默认采用的 READ_COMMITTED 隔离级别;

  • ISOLATION_READ_UNCOMMITTED:最低的隔离级别,允许读取,允许读取尚未提交的的数据变更,可能会导致脏读、幻读或不可重复读;

  • ISOLATION_READ_COMMITTED:允许读取并发事务已经提交的数据,可以阻止脏读,但是幻读或不可重复读仍有可能发生;

  • ISOLATION_REPEATABLE_READ:对同一字段的多次读取结果都是一致的,除非数据是被本身事务自己所修改,可以阻止脏读和不可重复读,但幻读仍有可能发生;

  • ISOLATION_SERIALIZABLE:最高的隔离级别,完全服从 ACID 的隔离级别。所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰,也就说,该级别可以阻止脏读、不可重复读以及幻读。但是这将严重影响程序的性能。通常情况下也不会用到该级别。

Spring 系列推荐

Spring04——Spring MVC 全解析

Spring03——有关于 Spring AOP 的总结

Spring02——Spring 中 Bean 的生命周期及其作用域

Spring01——你应该了解的,有关 IOC 容器的一切

你可能感兴趣的:(Spring05——Spring 如何实现事务管理)