• [Spring框架]Spring 事务管理基础入门总结.


    [Spring框架]Spring 事务管理基础入门总结.

     

    前言:
    在之前的博客中已经说过了数据库的事务, 不过那里面更多的是说明事务的一些锁机制, 今天来说一下Spring管理事务的一些基础知识. 
    之前的文章: [数据库事务与锁]详解一: 彻底理解数据库事务

    一, 什么是事务

    事务是逻辑上一组操作,这组操作要么全都成功,要么全都失败.

    事务的属性: ACID
    原子性(Atomicity): 事务作为一个整体被执行,包含在其中的对数据的操作要么全部被执行,要么都不执行.
    一致性(Consistency):事务应确保数据库的状态从一个一致状态转变为另一个一致状态. 一致状态的含义是数据库中的数据应满足为完整性约束.
    隔离性(Isolation):多个事务并发执行时, 一个事务的执行不应该影响其他事务的执行.
    持久性(Durability):一个事务一旦提交, 他对数据库的修改应该永久保存在数据库中.
      

    二, Spring的事务管理

    一类:编程式事务管理.手动编写代码管理事务.

    二类:声明式事务管理.通过配置完成事务管理.(AOP) : 这里只说声明式的事务管理.

    事务管理的API:

    PlatformTransactionManager :平台事务管理器

      * 是真正管理事务的对象.

    TransactionDefinition :事务定义信息.

      * 定义事务的(隔离级别,传播行为,超时信息,只读)

    TransactionStatus :事务状态.

      * 管理事务的过程中,事务有一些状态的改变.状态信息被记录在该对象中.

    Spring根据TransactionDefinition中定义的信息使用PlatformTransactionManager管理事务,管理事务过程中产生状态,将状态记录到TransactionStatus中.

     

    三, Spring相关API详解
    1,
    PlatformTransactionManager


    2,
    TransactionDefinition 

    常量:

      * ISOLATION_*:定义事务的隔离级别.
      

      * PROPAGATION_*:定义事务的传播行为.
      
      
    * 超时信息:
      
    方法:

      

    Transaction事务状态:
      |

    Spring的事务传播行为:

    复制代码
    PROPAGATION_REQUIRED :如果A,B操作,如果A有事务使用A的事务将B包含进来.如果A没有事务创建一个新事务将A,B包进来.
    PROPAGATION_SUPPORTS    :如果A,B操作,如果A有事务,使用A的事务将B包含进来.如果A没有事务,不使用事务.
    PROPAGATION_MANDATORY    :如果A,B操作,如果A有事务,使用A的事务将B包含进来.如果A没有事务,就会抛出异常.
    
    PROPAGATION_REQUIRES_NEW    :如果A,B操作,如果A有事务,将A的事务挂起.创建一个新事务执行B操作.
    PROPAGATION_NOT_SUPPORTED    :如果A,B操作,总是以非事务方式运行,如果A有,将A挂起.
    PROPAGATION_NEVER :如果A,B操作,总是以非事务方式运行,如果A有事务抛出异常.
    
    PROPAGATION_NESTED    :嵌套事务.如果A,B操作,A有事务,在A执行完之后设置一个保存点.如果B执行没有问题,一起提交.如果B出现问题.允许用户自己控制回滚到最初还是回滚到保存点.
    复制代码

     

    四, Spring事务管理实例(声明式事务管理)

    Spring声明式事务管理又可分为三种:
      1,
    基于TransactionProxyFactoryBean
       2, 基于AspectJ的XML方式的事务管理
      3, 基于AspectJ的注解方式事务管理

    基于AspectJ的XML方式的事务管理:
      1,引入开发包:
      

      2,Service层代码:
    AccountService.java

    复制代码
    1 public interface AccountService {
    2 
    3     /**
    4      * 转账的方法
    5      */
    6     public void transfer(String from,String to,Double money);
    7 }
    复制代码

    AccountServiceImpl.java:

    复制代码
     1     private AccountDao accountDao;
     2 
     3     public void setAccountDao(AccountDao accountDao) {
     4         this.accountDao = accountDao;
     5     }
     6 
     7     @Override
     8     /**
     9      * 业务层转账的方法:
    10      *     from:转出账号
    11      *     to:转入账号
    12      *     money:转账金额
    13      */
    14     public void transfer(final String from, final String to, final Double money) {
    15         accountDao.outMoney(from, money);
    16         int d = 1 / 0;
    17         accountDao.inMoney(to, money);
    18     }
    19 
    20 }
    复制代码

      3,DAO层代码
    AccountDAO.java:

    1 public interface AccountDao {
    2     public void outMoney(String from, Double money);
    3 
    4     public void inMoney(String to, Double money);
    5 }

    AccountDAOImpl.java:

    复制代码
     1 public class AccountDaoImpl extends JdbcDaoSupport implements AccountDao {
     2 
     3     @Override
     4     public void outMoney(String from, Double money) {
     5         this.getJdbcTemplate().update("update account set money = money - ? where name = ?", money,from);
     6     }
     7 
     8     @Override
     9     public void inMoney(String to, Double money) {
    10         this.getJdbcTemplate().update("update account set money = money + ? where name = ?", money,to);
    11     }
    12 
    13 }
    复制代码

      4,配置文件
    jdbc.properties:

    jdbc.driverClass=com.mysql.jdbc.Driver
    jdbc.url=jdbc:mysql:///spring_transaction
    jdbc.user=root
    jdbc.password=123

    applicationcontext.xml:

    复制代码
     1 <?xml version="1.0" encoding="UTF-8"?>
     2 <beans xmlns="http://www.springframework.org/schema/beans"
     3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     4     xmlns:context="http://www.springframework.org/schema/context"
     5     xmlns:aop="http://www.springframework.org/schema/aop"
     6     xmlns:tx="http://www.springframework.org/schema/tx"
     7     xsi:schemaLocation="http://www.springframework.org/schema/beans 
     8     http://www.springframework.org/schema/beans/spring-beans.xsd
     9     http://www.springframework.org/schema/context
    10     http://www.springframework.org/schema/context/spring-context.xsd
    11     http://www.springframework.org/schema/aop
    12     http://www.springframework.org/schema/aop/spring-aop.xsd
    13     http://www.springframework.org/schema/tx 
    14     http://www.springframework.org/schema/tx/spring-tx.xsd">
    15     
    16     <context:property-placeholder location="classpath:jdbc.properties"/>
    17     
    18     <!-- 配置C3P0连接池 -->
    19     <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
    20         <property name="driverClass" value="${jdbc.driverClass}"/>
    21         <property name="jdbcUrl" value="${jdbc.url}"/>
    22         <property name="user" value="${jdbc.user}"/>
    23         <property name="password" value="${jdbc.password}"/>
    24     </bean>
    25     <!-- 配置Service -->
    26     <bean id="accountService" class="cn.augmentum.transaction.demo3.service.AccountServiceImpl">
    27         <property name="accountDao" ref="accountDao"/>
    28     </bean>
    29     
    30     <!-- 配置DAO -->
    31     <bean id="accountDao" class="cn.augmentum.transaction.demo3.dao.AccountDaoImpl">
    32         <property name="dataSource" ref="dataSource"/>
    33     </bean>
    34     
    35     <!-- 配置事务管理器 -->
    36     <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    37         <property name="dataSource" ref="dataSource"/>
    38     </bean>
    39     
    40     <!-- 配置事务增强 -->
    41     <tx:advice id="txAdvice" transaction-manager="transactionManager">
    42         <tx:attributes>
    43             <!-- 
    44                 propagation:事务传播行为:
    45                 isolation:隔离级别
    46                 read-only:是否为只读事务.
    47                 timeout    :是否超时.
    48                 rollback-for:类似-Exception.发生哪些异常回滚事务.
    49                 no-rollback-for:类似+Exception.发生哪些异常不回滚.
    50              -->
    51             <tx:method name="transfer" propagation="REQUIRED"/>
    52         </tx:attributes>
    53     </tx:advice>
    54     
    55     
    56     <!-- AOP的配置 -->
    57     <aop:config>
    58         <aop:pointcut expression="execution(* cn.augmentum.transaction.demo3.service.AccountServiceImpl.*(..))" id="pointcut1"/>
    59         <aop:advisor advice-ref="txAdvice" pointcut-ref=""/>
    60     </aop:config>
    61 </beans>
    复制代码

      5, 测试方法
    SpringDemo.java:

    复制代码
     1 @RunWith(SpringJUnit4ClassRunner.class)
     2 @ContextConfiguration("classpath:applicationContext.xml")
     3 public class SpringDemo3 {
     4 
     5     @Resource(name="accountService")
     6     private AccountService accountService;
     7     
     8     @Test
     9     public void demo1(){
    10         accountService.transfer("老马", "凤姐", 1000d);
    11     }
    12 }
    复制代码


    关于XML的声明式事务管理就这些了, 那么下面来看下更简单的关于注解的声明式事务管理的做法.;
    这里只需要看Service层是如何加注解以及applicationcontext中是怎样配置的就行了.

    AccountServiceImpl.java:

    复制代码
     1 /**
     2  * @Transactional中属性
     3  * propagation:传播行为.
     4  * readOnly:是否只读
     5  * timeout:超时信息
     6  * isolation:隔离级别
     7  */
     8 @Transactional(propagation=Propagation.REQUIRED,readOnly=false,timeout=-1,isolation=Isolation.DEFAULT)
     9 public class AccountServiceImpl implements AccountService {
    10     private AccountDao accountDao;
    11 
    12     public void setAccountDao(AccountDao accountDao) {
    13         this.accountDao = accountDao;
    14     }
    15 
    16     @Override
    17     /**
    18      * 业务层转账的方法:
    19      *     from:转出账号
    20      *     to:转入账号
    21      *     money:转账金额
    22      */
    23     public void transfer(final String from, final String to, final Double money) {
    24         accountDao.outMoney(from, money);
    25         int d = 1 / 0;
    26         accountDao.inMoney(to, money);
    27     }
    28 }
    复制代码


    applicationcontext.xml:

    复制代码
     1 <?xml version="1.0" encoding="UTF-8"?>
     2 <beans xmlns="http://www.springframework.org/schema/beans"
     3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     4     xmlns:context="http://www.springframework.org/schema/context"
     5     xmlns:aop="http://www.springframework.org/schema/aop"
     6     xmlns:tx="http://www.springframework.org/schema/tx"
     7     xsi:schemaLocation="http://www.springframework.org/schema/beans 
     8     http://www.springframework.org/schema/beans/spring-beans.xsd
     9     http://www.springframework.org/schema/context
    10     http://www.springframework.org/schema/context/spring-context.xsd
    11     http://www.springframework.org/schema/aop
    12     http://www.springframework.org/schema/aop/spring-aop.xsd
    13     http://www.springframework.org/schema/tx 
    14     http://www.springframework.org/schema/tx/spring-tx.xsd">
    15     
    16     <context:property-placeholder location="classpath:jdbc.properties"/>
    17     
    18     <!-- 配置C3P0连接池 -->
    19     <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
    20         <property name="driverClass" value="${jdbc.driverClass}"/>
    21         <property name="jdbcUrl" value="${jdbc.url}"/>
    22         <property name="user" value="${jdbc.user}"/>
    23         <property name="password" value="${jdbc.password}"/>
    24     </bean>
    25     <!-- 配置Service -->
    26     <bean id="accountService" class="cn.augmentum.transaction.demo4.service.AccountServiceImpl">
    27         <property name="accountDao" ref="accountDao"/>
    28     </bean>
    29     
    30     <!-- 配置DAO -->
    31     <bean id="accountDao" class="cn.augmentum.transaction.demo4.dao.AccountDaoImpl">
    32         <property name="dataSource" ref="dataSource"/>
    33     </bean>
    34     
    35     <!-- 配置事务管理器 -->
    36     <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    37         <property name="dataSource" ref="dataSource"/>
    38     </bean>
    39     
    40     <!-- 开启注解事务 -->
    41     <tx:annotation-driven transaction-manager="transactionManager"/>
    42 </beans>
    复制代码

    注解方式的声明式事务管理也就是这么多, 看起来确实简单了很多.

  • 相关阅读:
    关于Lucas定理、多项式Exp的一些思考
    Binet-Cauchy定理的证明
    CSP2019 树上的数 题解
    Graphviz学习
    Luogu P2221 [HAOI2012]高速公路题解
    CSP2019 树的重心 题解
    CSP2019 Emiya 家今天的饭 题解
    UVA10559 方块消除 Blocks 题解
    关于二次项系数为1的二元一次不定方程解法的探究
    关于对STL容器重载运算符的问题
  • 原文地址:https://www.cnblogs.com/du-0210/p/8426700.html
Copyright © 2020-2023  润新知