06-Spring03-事务管理

今日知识

1. Spring事务管理
2. 转账案例

Spring事务管理

1. 事务特性(ACID)
    1. 原子性:整体 【原子性是指事务包含的所有操作要么全部成功,要么全部失败】
    2. 一致性:数据 【一个事务执行之前和执行之后都必须处于一致性状态】
    3. 隔离性:并发 【对于任意两个并发的事务T1和T2,在事务T1看来,T2要么在T1开始之前就已经结束,要么在T1结束之后才开始,这样每个事务都感觉不到有其他事务在并发地执行。】
    4. 持久性:结果 【持久性是指一个事务一旦被提交了,那么对数据库中的数据的改变就是永久性的】
* 隔离问题
    1. 脏读:一个事务读到另一个事务未提交的内容
    2. 不可重复读:一个事务读到另一个事务已提交的内容(update)这是大多数数据库系统的默认隔离级别(但不是MySQL默认的)。它满足了隔离的简单定义:一个事务只能看见已经提交事务所做的改变。
    3. 虚读:一个事务读到另一个事务已提交的内容(delete,insert),这是MySQL的默认事务隔离级别,它确保同一事务的多个实例在并发读取数据时,会看到同样的数据行。行数发生变化
    4. Serializable(可串行化)
    这是最高的隔离级别,它通过强制事务排序,使之不可能相互冲突,从而解决幻读问题。简言之,它是在每个读的数据行上加上共享锁。在这个级别,可能导致大量的超时现象和锁竞争。
* 隔离级别-解决问题
    1. read uncommitted,读未提交,存在三个问题
    2. read committed,读已提交,解决:脏读,存在两个问题
    3. repeatable read,可重复读,解决:脏读,和不可重复读,存在一个问题
    4. serializable,串行化。单事务。没有问题。一般不用,涉及IO操作,占用内存。
2. Spring提供的事务jar包
    * spring-tx jar包
    * jar 包包含三个顶级接口
        * PlatformTransactionManager:
        平台事务管理器,spring要管理事务,必须使用事务管理器,进行事务配置时,必须配置事务管理器
        * TransactionDefinition:
        事务详情(事务定义、事务属性),spring用于确定事务具体详情,
        * TransactionStatus:
        事务状态,spring用于记录当前事务运行状态。例如:是否有保存点,事务是否完成。
        spring底层根据状态进行相应操作。


3. 手动代理事务
    1. AccountServiceImpl写法注入TransactionTemplate
        * public class AccountServiceImpl implements AccountService {
    //spring底层使用 TransactionTemplate 事务模板进行操作。
    //注入已经 配置事务模板
    @Autowired
    TransactionTemplate transactionTemplate;
    //Spring注入AccountDao
    @Autowired
    AccountDao accountDao;
    public void tansfer(final String inner, final String outer, final Integer money) {
        //通过事务模板执行业务
        this.transactionTemplate.execute(new TransactionCallbackWithoutResult() {
            protected void doInTransactionWithoutResult(TransactionStatus transactionStatus) {
                //第一个进账
                accountDao.inner(inner,money);
                //第二个出账
               // int i=10/0;
                accountDao.out(outer,money);
            }
        });
    }
}
    2. xml中的配置
        * !--配置事务模板-->
    <bean id="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate">
        <property name="transactionManager" ref="txManager"></property>
    </bean>
    <!--配置一个事务管理器-->
    <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager
">
        <property name="dataSource" ref="dataSource"></property>
    </bean>
4. 工厂bean生成代理事务:半自动
    1. transactionAttributes:事务详情
        prop.key :确定哪些方法使用当前事务配置
        prop.text:用于配置事务详情
    	格式:PROPAGATION,ISOLATION,readOnly,-Exception,+Exception
    	传播行为		 隔离级别	      是否只读	异常回滚	      异常提交
    2. AccountServiceImpl2直接普通的写法,不用引入TransactionTemplate事务模板
    3. xml中的配置
        * <!--配置accountService2,bean-->
    <bean id="accountService" class="com.rqy.service.impl.AccountServiceImpl2"/>
    <!--配置管理事务的代理工厂,代替上面的方法,到达半自动代理-->
    <bean id="proxyAccountService" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
        <!--配置接口-->
        <property name="proxyInterfaces" value="com.rqy.service.AccountService"/>
        <!--目标对象-->
        <property name="target" ref="accountService"/>
        <!--事务管理器-->
        <property name="transactionManager" ref="txManager"/>
        <!--事务详情-->
        <!--
        transactionAttributes:事务详情
        prop.key :确定哪些方法使用当前事务配置
        prop.text:用于配置事务详情
	    格式:PROPAGATION,ISOLATION,readOnly,-Exception,+Exception
	    传播行为		 隔离级别	      是否只读	异常回滚	      异常提交
        -->
        <property name="transactionAttributes">
            <props>
                <prop key="transfer">PROPAGATION_REQUIRED,ISOLATION_REPEATABLE_READ</prop>
            </props>
        </property>
    </bean>
    <!--配置一个事务管理器-->
    <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager
">
        <property name="dataSource" ref="dataSource"></property>
    </bean>

基本AOP的事务配置(全自动)

1. xml配置(方法一)
    1. <!--配置一个事务管理器-->
    <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager
">
        <property name="dataSource" ref="dataSource"></property>
    </bean>
    <!--配置事务属性,同时引入事务管理器-->
    <tx:advice id="txAdvice" transaction-manager="txManager">
        <tx:attributes>
            <!--transfer。。。方法可读,-->
            <tx:method name="transfer*" propagation="REQUIRED" isolation="REPEATABLE_READ"/>
            <!-- 其它方法加可读写事务 -->
            <tx:method name="*"/>
        </tx:attributes>
    </tx:advice>
    <!-- 配置AOP:告诉spring框架哪些方法需要管理事务 -->
    <aop:config>
        <!-- 指定切入点 -->
        <aop:advisor advice-ref="txAdvice" pointcut="execution(* com.rqy.service.*.*(..))"/>
    </aop:config>
2. 注解事务(方法二)
    1. 类里面加注解事务,就不用指明切入点了,默认在该类中加入该事务管理
    2. xml需要声明自动开启事务注解驱动:<tx:annotation-driven transaction-manager="txManager"></tx:annotation-driven>
    3. 注解直接加在方法上面
        * @Transactional(propagation = Propagation.REQUIRED,isolation = Isolation.DEFAULT)
        * @Transactional:直接写这个就置默认隔离级别和传播行为

纯javaConfig(全注解配置)

1. 类上面声明
    //声明我是配置文件
    @Configuration
    //声明扫描范围
    @ComponentScan(basePackages = "com.rqy")
    //声明自动开启事务注解
    @EnableTransactionManagement
    //开启AspectJ注解
    @EnableAspectJAutoProxy
2. 注解类
    * //声明我是配置文件
    @Configuration
    //声明扫描范围
    @ComponentScan(basePackages = "com.rqy")
    //声明自动开启事务注解
    @EnableTransactionManagement
    //开启AspectJ注解
    @EnableAspectJAutoProxy
    public class SpringConfig {
//配置数据源
@Bean
public ComboPooledDataSource comboPooledDataSource() throws PropertyVetoException {
    ComboPooledDataSource comboPooledDataSource = new ComboPooledDataSource();
    comboPooledDataSource.setDriverClass("com.mysql.jdbc.Driver");
    comboPooledDataSource.setJdbcUrl("jdbc:mysql://localhost:3306/spring_day04?serverTimezone=UTC");
    comboPooledDataSource.setUser("root");
    comboPooledDataSource.setPassword("123456");
    return comboPooledDataSource;
}
//配置JdbcTemplate
@Bean
public JdbcTemplate jdbcTemplate(ComboPooledDataSource dataSource){
    JdbcTemplate jdbcTemplate = new JdbcTemplate();
    jdbcTemplate.setDataSource(dataSource);
    return jdbcTemplate;
}
//配置事务管理器
@Bean
public DataSourceTransactionManager dataSourceTransactionManager(ComboPooledDataSource dataSource){
    DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager();
    dataSourceTransactionManager.setDataSource(dataSource);
    return dataSourceTransactionManager;
    }
}
3. 实例类
    * @Component
    public class AccountDaoImpl2  implements AccountDao {
        @Autowired
        JdbcTemplate jdbcTemplate;
        public void out(String outer, Integer money) {
            String sql = "update account set money=money-? where username=?";
            jdbcTemplate.update(sql, money, outer);
        }
        public void inner(String inner, Integer money) {
            String sql = "update account set money=money+? where username=?";
            jdbcTemplate.update(sql, money, inner);
        }
    }
    * @Transactional
        @Component("accountService5")
        public class AccountServiceImpl5 implements AccountService {
            @Autowired
            AccountDao accountDao;
            public void transfer( String inner,  String outer,  Integer money) {
                //第一个进账
                accountDao.inner(inner,money);
                //第二个出账
                int i=10/0;
                accountDao.out(outer,money);
            }
        }
4. 测试类
    * @RunWith(SpringJUnit4ClassRunner.class)
        //不加载配置文件的写法,如果有多个配置类,用,隔开。
        @ContextConfiguration(classes = {SpringConfig.class})
        public class ConfigTest {
            //去找代理对象
            @Autowired
            @Qualifier("accountService5")
            AccountService accountService;
            @Test
            public void test(){
                accountService.transfer("rose","jack",2000);
            }
        }

传播行为

1. PROPAGATION_REQUIRED
required , 必须  【默认值】
    * 支持当前事务,A如果有事务,B将使用该事务。
如果A没有事务,B将创建一个新的事务。
2. PROPAGATION_SUPPORTS:supports     ·   
    * 支持当前事务,A如果有事务,B将使用该事务。
    如果A没有事务,B将以非事务执行。
3. PROPAGATION_REQUIRES_NEW:如果A有事务,将A的事务挂起,B创    建一个新的事务如果A没有事务,B创建一个新的事务
posted @ 2019-07-31 17:42  励志前行  阅读(133)  评论(0编辑  收藏  举报