基于XML方式的事务式事务-spring学习07

Spring的事务管理

理解事务之前:说一个列子,取钱,比如你去ATM机取1000块钱,大体有两个步骤:首先输入密码金额,银行卡扣掉1000元钱;然后ATM出1000元钱。这两个步骤必须是要么都执行要么都不执行。如果银行卡扣除了1000块但是ATM出钱失败的话,你将会损失1000元;如果银行卡扣钱失败但是ATM却出了1000块,那么银行将损失1000元。所以,如果一个步骤成功另一个步骤失败对双方都不是好事,如果不管哪一个步骤失败了以后,整个取钱过程都能回滚,也就是完全取消所有操作的话,这对双方都是极好的。 
事务就是用来解决类似问题的。事务是一系列的动作,它们综合在一起才是一个完整的工作单元,这些动作必须全部完成,如果有一个失败的话,那么事务就会回滚到最开始的状态,仿佛什么都没发生过一样。 
在企业级应用程序开发中,事务管理必不可少的技术,用来确保数据的完整性和一致性。

​ 事务的特性:

  • 原子性:要么全做,要么全不做。
  • 一致性:一旦事务完成(不管成功还是失败),系统必须确保它所建模的业务处于一致的状态,而不会是部分完成部分失败。在现实中的数据不应该被破坏。
  • 隔离性:可能有许多事务会同时处理相同的数据,因此每个事务都应该与其他事务隔离开来,防止数据损坏。
  • 持久性: 一旦事务完成,无论发生什么系统错误,它的结果都不应该受到影响,这样就能从任何系统崩溃中恢复过来。通常情况下,事务的结果被写到持久化存储器中。
1.事务管理的核心接口

​ spring的jar包中,包含一个名为spring-tx-4.3.6RELEASE的JAR包。该包就是spring提供的用于事务管理的依赖包。在该包的org.springframework.transaction包中,包含事务管理的三个核心接口。

  • PlatformTransactionManager接口:

​ 提供的平台事务管理器,用于管理事务。

​ TransactionStatus getTransaction(TransactionDefinition definition):用于获取事务状态信息。Spring 将 xml 中配置的事务详细信息封装到对象 TransactionDefinition 中,然后通过事务管理器的 getTransaction() 方法获得事务的状态(TransactionStatus),并对事务进行下一步的操作。

void commit(TransactionStatus status):用于提交事务。

void rollback(TransactionStatus status):用于回滚事务。

  • TransactionDefinition接口
    TransactionDefinition 接口是事务定义(描述)的对象,它提供了事务相关信息获取的方法,其中包括五个操作,具体如下。
  1. String getName():获取事务对象名称。
  2. int getIsolationLevel():获取事务的隔离级别。
  3. int getPropagationBehavior():获取事务的传播行为。
  4. int getTimeout():获取事务的超时时间。
  5. boolean isReadOnly():获取事务是否只读。
  • TransactionStatus接口
    TransactionStatus 接口是事务的状态,它描述了某一时间点上事务的状态信息。其中包含六个操作.
    1. void flush();刷新事务
    2. boolean hasSavepoint();获取是否存在保存点
    3. boolean isCompleted();获取事务是否完成
    4. boolean isNewTransaction();获取是否是新事务
    5. boolean isRollbackOnly();获取是否回滚
    6. void setRollbackOnly();设置事务回滚
2.声明式事务管理:

​ 2.1:基于XML的方式:

​ 接口类

 //outUser汇款人   inUser收款人   
    public void transfer(String outUser,String inUser,Double money);
}

​ 实现类

public void transfer(String outUser, String inUser, Double money) {

    this.jdbcTemplate.update("update account set balance = balance +?"+
            "where username = ?",money,inUser);

    this.jdbcTemplate.update("update account set balance = balance -?"+
            "where username = ?",money,outUser);
}

​ 控制类

@Controller
public class AccountController {
}

​ 实体类

public class Account {
    private Integer id;
    private String username;
    private Double balance;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public Double getBalance() {
        return balance;
    }

    public void setBalance(Double balance) {
        this.balance = balance;
    }

    public String toString() {
        return "Account [id=" + id + ", "
                + "username=" + username + ", "
                + "balance=" + balance + "]";
    }
}

​ 测试类

public class TransactionTest {
    public static void main(String[] args) {
        ApplicationContext applicationContext=new ClassPathXmlApplicationContext("bean.xml");
        AccountDao accountDao = (AccountDao) applicationContext.getBean("accountDao");
        accountDao.transfer("Tom", "man", 1000.0);
        System.out.println("转账成功----------");
    }
}

基于事务管理的配置代码----》重点(学习里面代码注释)

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
       http://www.springframework.org/schema/tx
        http://www.springframework.org/schema/tx/spring-tx-4.3.xsd
          http://www.springframework.org/schema/context
         http://www.springframework.org/schema/context/spring-context-4.3.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop-4.3.xs
">
    <!-- 1.配置数据源-->
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <!--数据库驱动-->
        <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
        <!--连接数据库的url-->
        <property name="url" value="jdbc:mysql://localhost:3306/spring"/>
        <!--连接数据库的用户名-->
        <property name="username" value="root"/>
        <!--连接数据库的密码-->
        <property name="password" value="123456"/>
    </bean>

    <!--  2.配置JDBC模板-->
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <!--默认必须使用数据源-->
        <property name="dataSource" ref="dataSource"/>
    </bean>
    <!--  3.定义id为accountDao的Bean-->
    <bean id="accountDao" class="com.lz.jiaotong.dao.impl.AccountDaoImpl">
        <!--将jdbcTempla注入到accountDao实例中-->
        <property name="jdbcTemplate" ref="jdbcTemplate"/>
    </bean>
    <!--  4.事务管理器,依赖于数据源-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>
    <!--  5.编写通知,对事务增强,需要编写对切入点和具体执行事务细节-->
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <tx:attributes>
            <tx:method name="*" propagation="REQUIRED" isolation="DEFAULT" read-only="false"/>
        </tx:attributes>
    </tx:advice>
    <!--  6.编写aop 让spring对目标自动生成代理需要使用AspectJ的表达式-->
    <aop:config>
        <aop:pointcut expression="execution(* com.lz.jiaotong.dao.impl.*.*(..))" id="txPointcut"/>
<!--  切面  :将切入点与通知整合-->
        <aop:advisor advice-ref="txAdvice" pointcut-ref="txPointcut"/>
    </aop:config>
</beans>
上一篇:浅析Mysql的隔离级别及MVCC


下一篇:math