欢迎使用CSDN-markdown编辑器

目标
1、事务回顾 :基本概念
2、Spring事务管理的一组API :通过api管理spring事务
3、Spring的编程式事务管理
4、Spring的声明式事务管理

1、事务回顾:
· 什么是事务?
事务指的是逻辑上的一组操作,这组操作要么全部成功,要不全部失败

·事务的特性:
    原子性:原子性是指事务是一个不可分割的工作单位,事物中的操作要么都发生,要么都不发生
    一致性:一致性指事务前后数据的完整性必须保持一致
    隔离性:隔离性指多个用户并发访问数据库时,一个用户的事务不能被其他用户的事务所干扰,多个并发事务之间数据要互相隔离  (可设置隔离级别)
    持久性:持久性是指一个事物一旦被提交,他对数据库中数据的改变就是永久性的,即使数据库发生故障也不应该对其有任何影响

· Spring 事务管理高层抽象主要包括3个接口
· Platform TransactionManager 事务管理器

    管理事务— 提交、回滚
Spring为不同的持久化框架提供了不同PlatformTransactoinManager接口实现

这里写图片描述

· TransactionDefinition 事务定义信息(隔离、传播、超时、只读)
事务定义信息—隔离级别、传播行为、是否超时、是否只读
如果不考虑隔离性,会引发安全问题如下:

    脏读:
      一个事务读取了领一个事务改写但还未提交的数据,如果这些数据被回滚,则读到的数据是无效的。

   不可重复读:
      在同一事务中,多次读取同一数据返回的结果有所不同
    幻读:
      一个事务读取了几行记录后,另一个事务插入一些记录,幻读就发生了。
      再后来的查询中,第一个事务就会发现有些原来没有的记录

这里写图片描述

传播行为:

这里写图片描述
这里写图片描述

· TransactionStatus 事务具体运行状态
运行状态—是不是提交、有没有保存点、是不是新事务

Spring 支持两种方法的事务管理
    -编程式的事务管理
        · 在实际应用中很少使用
        · 通过TransactionTemplate手动管理事务
           · 在AccountService中使用TransactionTemplate
           · TransactionTemplate依赖DataSourceTransactionManager
           · DataSourceTransactionManager依赖DataSource构造

//注入转账的Dao的类
    private AccountDao accountDao;
    //注入事务管理的模板
    private TransactionTemplate transactionTemplate;


    /***
     *  Java
     * @param out 转出账号
     * @param in 转入账号
     * @param money 转出金额
     */
    @Override
    public void transfer(final String out, final String in, final Double money) {
        transactionTemplate.execute(new TransactionCallbackWithoutResult() {

            @Override
            protected void doInTransactionWithoutResult(TransactionStatus transactionStatus) {
                accountDao.outMoney(out, money);
                //int i=1/0;
                accountDao.inMoney(in, money);

            }
        });
    }
Spring 支持两种方法的事务管理
    -编程式的事务管理
            · 在实际应用中很少使用
            · 通过TransactionTemplate手动管理事务
            · 在AccountService中使用TransactionTemplate
            · TransactionTemplate依赖DataSourceTransactionManager
            · DataSourceTransactionManager依赖DataSource构造
<!-- applicationContext.xml -->
<!-- 引入外部属性文件 -->

    <context:property-placeholder location="classpath:jdbc.properties"/>

    <!-- 配置c3p0连接池 -->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass" value="${jdbc.driverClass}" />
        <property name="jdbcUrl" value="${jdbc.url}" />
        <property name="user" value="${jdbc.username}" />
        <property name="password" value="${jdbc.password}" />
    </bean>

    <!-- 配置业务层类 -->
    <bean id="accountService" class="cn.muke.spring.demo1.AccountServiceImpl">
        <property name="accountDao" ref="accountDao" />
        <!-- 注入事务的模板 -->
        <property name="transactionTemplate" ref="transactionTemplate" />
    </bean>

    <!-- 配置Dao层类 -->
    <bean id="accountDao" class="cn.muke.spring.demo1.AccountDaoImpl">
        <!-- 注入连接池 -->
        <property name="dataSource" ref="dataSource"></property>
    </bean>

    <!-- 配置事务管理器 -编程式事务 -->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <!-- 注入连接池 -->
        <property name="dataSource" ref="dataSource" />
    </bean>

    <!-- 配置事务管理模板:Spring为了简化事务管理的代码所提供的类 -->
    <bean id="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate">
        <!-- 注入事务管理器 -->
        <property name="transactionManager" ref="transactionManager" />
    </bean>
-使用XML配置声明式事务
    · 开发中推荐使用(代码侵入性最小)
    · Spring的声明式事务是通过AOP实现
/***
 * 测试   
 * 转账案例测试类
 * @author smallearly
 *
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class SpringDemo1 {

    @Resource(name="accountService")
    private AccountService accountService;

    @Test
    public void demo1(){
        accountService.transfer("aaa", "bbb", 200d);
    }

}
<?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:context="http://www.springframework.org/schema/context"
     xmlns:aop="http://www.springframework.org/schema/aop"
     xmlns:tx="http://www.springframework.org/schema/tx"
     xmlns:task="http://www.springframework.org/schema/task"
     xsi:schemaLocation="http://www.springframework.org/schema/beans
         http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
         http://www.springframework.org/schema/context
         http://www.springframework.org/schema/context/spring-context-3.1.xsd
         http://www.springframework.org/schema/aop
         http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
         http://www.springframework.org/schema/tx
         http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
         http://www.springframework.org/schema/task
         http://www.springframework.org/schema/task/spring-task-3.1.xsd">

    <!-- 引入外部属性文件 -->

    <context:property-placeholder location="classpath:jdbc.properties"/>

    <!-- 配置c3p0连接池 -->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass" value="${jdbc.driverClass}" />
        <property name="jdbcUrl" value="${jdbc.url}" />
        <property name="user" value="${jdbc.username}" />
        <property name="password" value="${jdbc.password}" />
    </bean>

    <!-- 配置业务层类 -->
    <bean id="accountService" class="cn.muke.spring.demo2.AccountServiceImpl">
        <property name="accountDao" ref="accountDao" />

    </bean>

    <!-- 配置Dao层类 -->
    <bean id="accountDao" class="cn.muke.spring.demo2.AccountDaoImpl">
        <!-- 注入连接池 -->
        <property name="dataSource" ref="dataSource"></property>
    </bean>

    <!-- 配置事务管理器 -->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <!-- 注入连接池 -->
        <property name="dataSource" ref="dataSource" />
    </bean>

    <!-- 配置业务层代理 -->
    <bean id="accountServiceProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
        <!-- 配置目标对象 -->
        <property name="target" ref="accountService" />
        <!-- 注入事务管理器 -->
        <property name="transactionManager" ref="transactionManager" />
        <!-- 注入事务属性 -->
        <property name="transactionAttributes">
            <props>
                <!-- prop的格式
                        * PROPAGATION   :事务的传播行为
                        * ISOLATION     :事务的隔离级别
                        * readOnly      :只读(不能 修改、插入、删除)
                        * -Exception    :发生什么异常回滚事务
                        * +Exception    :发生什么异常不回滚事务
                 -->
                <prop key="transfer">PROPAGATION_REQUIRED,+java.lang.ArithmeticException</prop>
            </props>
        </property>
    </bean>

</beans>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章