美文网首页
Spring事务管理

Spring事务管理

作者: codersm | 来源:发表于2017-06-10 15:33 被阅读29次

    Spring框架为事务管理提供了一致的抽象,可以带来以下好处:

    • Java Transaction API(JTA),JDBC,Hibernate,Java Persistence API(JPA)和Java数据对象(JDO)等不同的事务API之间的一致的编程模型
    • 支持声明事务管理
    • 编程式事务管理的API使用简单
    • 与Spring的数据访问抽象集成

    1、Spring一致的编程模型

    传统上,Java EE开发人员有两种交易管理选择:全局或本地交易,两者都有明显的局限性。

    • 全局事务
      JTA、EJB

    优点:可以多资源使用
    缺点:JTA API笨重、通过JNDI获取资源。

    • 本地事务
      本地事务是资源专用,比如:JDBC连接。

    优点:简单易用。
    缺点:不能多资源使用。

    1.1、理解Spring事务抽象

    Spring事务抽象最重要是事务策略概念,事务策略由org.springframework.transaction.PlatformTransactionManager定义:

    public interface PlatformTransactionManager {
    
        TransactionStatus getTransaction(
                TransactionDefinition definition) throws TransactionException;
    
        void commit(TransactionStatus status) throws TransactionException;
    
        void rollback(TransactionStatus status) throws TransactionException;
    }
    

    TransactionStatus表示一个新的事务或者当前调用堆栈中存在匹配事务,和执行线程相关联。TransactionStatus实例需要依赖一个
    TransactionDefinition实例参数,TransactionDefinition接口定义如下:

    public interface TransactionDefinition {
    
        // 事务传播
        int getPropagationBehavior();
    
        // 事务隔离级别
        int getIsolationLevel();
    
        // 事务超时事务
        int getTimeout();
    
        boolean isReadOnly();
    
        String getName();
    
    }
    

    TransactionStatus接口定义:

    public interface TransactionStatus extends SavepointManager, Flushable {
    
        boolean isNewTransaction();
    
        boolean hasSavepoint();
    
        void setRollbackOnly();
    
        boolean isRollbackOnly();
    
        void flush();
    
        boolean isCompleted();
    
    }
    

    1.2、理解声明式事务

    关于Spring Framework的声明式事务支持的最重要的概念是通过AOP代理启用此支持,并且事务性建议由元数据驱动(目前基于XML或基于注释的),AOP与事务元数据的组合产生一个AOP代理,它使用TransactionInterceptor与适当的PlatformTransactionManager实现结合来驱动方法调用的事务。

    事务调用过程如下:

    事务调用过程

    1.2.1、声明式事务示例

    • 基于XML方式

      (1)创建对应数据库DO

          public class User {
      
          private Integer id;
      
          private String name;
          
          private Integer age;
      
          private Integer sex;
      
          public User(Integer id, String name, Integer age, Integer sex) {
              this.id = id;
              this.name = name;
              this.age = age;
              this.sex = sex;
          }
      
          public Integer getId() {
              return id;
          }
      
          public void setId(Integer id) {
              this.id = id;
          }
      
          public String getName() {
              return name;
          }
      
          public void setName(String name) {
              this.name = name;
          }
      
          public Integer getAge() {
              return age;
          }
      
          public void setAge(Integer age) {
              this.age = age;
          }
      
          public Integer getSex() {
              return sex;
          }
      
          public void setSex(Integer sex) {
              this.sex = sex;
          }
      }
      

      (2)、创建表与实体间映射

      public class UserRowMapper implements RowMapper<User>{
      
              public User mapRow(ResultSet resultSet, int i) throws SQLException {
      
                  User person = new User(
                              resultSet.getInt("id"),
                              resultSet.getString("name"),
                              resultSet.getInt("age"),
                              resultSet.getInt("sex"));
                  return person;
              }
          } 
      
      

      (3)、创建UserService接口

      public interface UserService {
      
                  void save(User user);
      }
      

      (4)、创建UserService接口实现类

      public class UserServiceImpl implements UserService {
      
          private final static Logger logger = LoggerFactory.getLogger(UserServiceImpl.class);
      
          @Resource
          private JdbcTemplate jdbcTemplate;
      
          @Override
          public void save(User user) {
      
              jdbcTemplate.update("INSERT INTO user(name,age,sex) VALUES (?,?,?)",
                      new Object[]{user.getName(), user.getAge(), user.getSex()},
                      new int[]{Types.VARCHAR, Types.INTEGER, Types.VARCHAR});
          }
      }
      

      (5)、创建Spring配置文件

          <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
              <property name="driverClass" value="com.mysql.jdbc.Driver"/>
              <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/test"/>
              <property name="user" value="root"/>
              <property name="password" value="root"/>
          </bean>
      
          <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
              <property name="dataSource" ref="dataSource"/>
          </bean>
      
          <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
              <property name="dataSource" ref="dataSource"/>
          </bean>
      
          <tx:advice id="txAdvice" transaction-manager="txManager">
              <!-- the transactional semantics... -->
              <tx:attributes>
                  <!-- all methods starting with 'get' are read-only -->
                  <tx:method name="get*" read-only="true"/>
                  <!-- other methods use the default transaction settings (see below) -->
                  <tx:method name="*"/>
              </tx:attributes>
          </tx:advice>
      
      
          <aop:config>
              <aop:pointcut id="serviceOperation"
                          expression="execution(* com.codersm.study.spring.tx.service.UserService.*(..))"/>
              <aop:advisor advice-ref="txAdvice" pointcut-ref="serviceOperation"/>
          </aop:config>
      
          <bean id="userService" class="com.codersm.study.spring.tx.service.impl.UserServiceImpl"/>
      
    • 基于注解方式

    1.3、事务传播

    1.4、其他

    1.4.1、Using @Transactional with AspectJ

    It is also possible to use the Spring Framework’s @Transactional support outside of a Spring container by means of an AspectJ aspect.

    1.4.2、事务绑定事件

    1.5 源码分析

    <<tx:advice>>标签 = org.springframework.transaction.interceptor.TransactionInterceptor

    image.png

    相关文章

      网友评论

          本文标题:Spring事务管理

          本文链接:https://www.haomeiwen.com/subject/sziqqxtx.html