zoukankan      html  css  js  c++  java
  • spring事务管理

    1、事务

    (1)概念

    一组业务操作,要求要么全不成功,要么全部不成功

    (2)特性(ACID)

    原子性、一致性、隔离性、持久性

    (3)隔离问题

    脏读

    不可重复读

    幻读

    (4)隔离级别

    ISOLATION_DEFAULT: 使用后端数据库默认的隔离级别
    ISOLATION_READ_UNCOMMITTED : 允许读取未提交的数据变更,可能会导致脏读,幻读或不可重复读
    ISOLATION_READ_COMMITTD : 允许读取为提交数据,可以阻止脏读,当时幻读或不可重复读仍可能发生
    ISOLATION_REPEATABLE_READ: 对统一字段多次读取结果是一致的,除非数据是被本事务自己修改.可以阻止脏读,不可重复读,但幻读可能
    发生
    ISOLATION_SERIALIZABLE : 完全服从ACID

    (5)savePoint(保存点)

    记录操作的当前位置,之后可以回滚到指定指定的位置(可以回滚一部分)

    2、spring的事务管理

    (1)导包

    tx:

    事务管理器:

     第一个jdbc的时候使用,第二个整合hibernate的时候使用

    (2)三个顶级接口

     (3)传播行为

     第一个为默认值

    3、手动管理事务

    (1)创建表

     (2)导入jar包

    核心:4+1

    aop:aop联盟、spring aop、aspectj规范、spring aspect

    数据库:jdbc、tx

    连接池:C3P0

     (3)创建Dao层和Service层的接口和接口的实现类:

    Dao层:

    public interface AccountDao {
        void out(String outer,Integer money);
        void in(String inner,Integer money);
    }
     

    Service层:

    public interface AccountService {
         void transfer(String outer,String inner,Integer money);
    }
    public class AccountServiceImpl implements AccountService {
        private AccountDao accountDao;
        private TransactionTemplate transactionTemplate;
        @Override
        public void transfer(final String outer,final String inner,final Integer money) {
            transactionTemplate.execute(new TransactionCallbackWithoutResult() {
                @Override
                protected void doInTransactionWithoutResult(TransactionStatus transactionStatus) {
                    accountDao.out(outer, money);
                    int i=1/0;
                    accountDao.in(inner, money);
                }
            });
    
        }
    
        public void setAccountDao(AccountDaoImpl accountDao) {
            this.accountDao=accountDao;
        }
    
        public void setTransactionTemplate(TransactionTemplate transactionTemplate) {
            this.transactionTemplate=transactionTemplate;
        }
    }

    在实现类里面制造异常,用于校验

    (4)配置文件:

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:aop="http://www.springframework.org/schema/aop"
           xmlns:context="http://www.springframework.org/schema/context"
           xmlns="http://www.springframework.org/schema/beans"
           xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans.xsd
           http://www.springframework.org/schema/aop
           http://www.springframework.org/schema/aop/spring-aop.xsd
           http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/spring-context.xsd">
        <!--将连接池放入Spring容器-->
        <bean name="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
            <property name="driverClass" value="com.mysql.jdbc.Driver"></property>
            <property name="jdbcUrl" value="jdbc:mysql:///bank_transfer"></property>
            <property name="user" value="root"></property>
            <property name="password" value="root"></property>
        </bean>
        <!--创建模板-->
        <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>
        <bean id="accountDao" class="pers.zhb.dao.AccountDaoImpl">
            <property name="dataSource" ref="dataSource"></property>
        </bean>
        <bean id="accountService" class="pers.zhb.service.AccountServiceImpl">
            <property name="accountDao" ref="accountDao"></property>
            <property name="transactionTemplate" ref="transactionTemplate"></property>
        </bean>
    </beans>

    (5)测试:

    public class Test {
        public static void main(String[] args) {
            ApplicationContext applicationContext=new
                    ClassPathXmlApplicationContext("applicationContext.xml");
            AccountService accountService =(AccountService) applicationContext.getBean("accountService");
            accountService.transfer("zhai","zhang",10);
        }
    }

    在出现异常后不管是转账方还是收款方,金额均未发生变化

    4、aop配置基于xml

    (1)创建Service层和Dao层以及接口和接口的实现类:

    Service层:

    public interface AccountService {
         void transfer(String outer,String inner,Integer money);
    }
    public class AccountServiceImpl implements AccountService {
        private AccountDao accountDao;
        private TransactionTemplate transactionTemplate;
        @Override
        public void transfer( String outer, String inner, Integer money) {
                    accountDao.out(outer, money);
                    int num=1/0;
                    accountDao.in(inner, money);
        }
    
        public void setAccountDao(AccountDaoImpl accountDao) {
            this.accountDao=accountDao;
        }
    
        public void setTransactionTemplate(TransactionTemplate transactionTemplate) {
            this.transactionTemplate=transactionTemplate;
        }
    }

    Dao层:

    public interface AccountDao {
        void out(String outer,Integer money);
        void in(String inner,Integer money);
    }
    public class AccountDaoImpl extends JdbcDaoSupport implements AccountDao{
        @Override
        public void out(String outer, Integer money) {
            this.getJdbcTemplate().update("update transfer set money=money-? where username=?",money,outer);
        }
    
        @Override
        public void in(String inner, Integer money) {
            this.getJdbcTemplate().update("update transfer set money=money+? where username=?",money,inner);
        }
    }

    (2)配置文件:

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:aop="http://www.springframework.org/schema/aop"
           xmlns="http://www.springframework.org/schema/beans"
           xmlns:tx="http://www.springframework.org/schema/tx"
           xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans.xsd
           http://www.springframework.org/schema/aop
           http://www.springframework.org/schema/aop/spring-aop.xsd
           http://www.springframework.org/schema/tx
           http://www.springframework.org/schema/tx/spring-tx.xsd">
        <!--将连接池放入Spring容器-->
        <bean name="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
            <property name="driverClass" value="com.mysql.jdbc.Driver"></property>
            <property name="jdbcUrl" value="jdbc:mysql:///bank_transfer"></property>
            <property name="user" value="root"></property>
            <property name="password" value="root"></property>
        </bean>
        <bean id="accountDao" class="pers.zhb.dao.AccountDaoImpl">
            <property name="dataSource" ref="dataSource"></property>
        </bean>
        <bean id="accountService" class="pers.zhb.service.AccountServiceImpl">
            <property name="accountDao" ref="accountDao"></property>
        </bean>
        <!--配置事务管理器-->
        <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
            <property name="dataSource" ref="dataSource"></property>
        </bean>
        <!--事务详情(通知),在aop筛选的基础上,对方法确定用什么样的事务
        propagation:传播行为
        isolation:隔离级别
        -->
        <tx:advice id="txAdvice" transaction-manager="txManager">
            <tx:attributes>
                <tx:method name="transfer()" propagation="REQUIRED" isolation="DEFAULT"/>
            </tx:attributes>
        </tx:advice>
        <!--aop编程,目标类有四个连接点,切入点表达式确定增强的连接器,从而获得切入点-->
        <aop:config>
            <aop:advisor advice-ref="txAdvice" pointcut="execution(* pers.zhb.service..*.*(..))"></aop:advisor>
        </aop:config>
    
    
    </beans>

    (3)测试类:

    public class Test {
        public static void main(String[] args) {
            ApplicationContext applicationContext=new
                    ClassPathXmlApplicationContext("applicationContext.xml");
            AccountService accountService =(AccountService) applicationContext.getBean("accountService");
            accountService.transfer("zhai","zhang",10);
        }
    }

    没有异常发生的时候能够保证转账金额的减少量和收款人的金额的增加量是一样的,当有异常发生时,转账方和收款方的金额都不会发生变化。

    5、注解方式

    (1)Dao层和Service层的接口和接口的实现类:

    Dao层:

    public interface AccountDao {
        void out(String outer,Integer money);
        void in(String inner,Integer money);
    }
    public class AccountDaoImpl extends JdbcDaoSupport implements AccountDao{
        @Override
        public void out(String outer, Integer money) {
            this.getJdbcTemplate().update("update transfer set money=money-? where username=?",money,outer);
        }
    
        @Override
        public void in(String inner, Integer money) {
            this.getJdbcTemplate().update("update transfer set money=money+? where username=?",money,inner);
        }
    }

    Service层:

    public interface AccountService {
         void transfer(String outer,String inner,Integer money);
    }
    @Transactional(propagation = Propagation.REQUIRED,isolation = Isolation.DEFAULT)
    public class AccountServiceImpl implements AccountService {
        private AccountDao accountDao;
        private TransactionTemplate transactionTemplate;
        @Override
    
        public void transfer( String outer, String inner, Integer money) {
                    accountDao.out(outer, money);
    
                    accountDao.in(inner, money);
        }
    
        public void setAccountDao(AccountDaoImpl accountDao) {
            this.accountDao=accountDao;
        }
    
        public void setTransactionTemplate(TransactionTemplate transactionTemplate) {
            this.transactionTemplate=transactionTemplate;
        }
    }

    (2)配置文件:

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:aop="http://www.springframework.org/schema/aop"
           xmlns="http://www.springframework.org/schema/beans"
           xmlns:tx="http://www.springframework.org/schema/tx"
           xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans.xsd
           http://www.springframework.org/schema/aop
           http://www.springframework.org/schema/aop/spring-aop.xsd
           http://www.springframework.org/schema/tx
           http://www.springframework.org/schema/tx/spring-tx.xsd">
        <!--将连接池放入Spring容器-->
        <bean name="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
            <property name="driverClass" value="com.mysql.jdbc.Driver"></property>
            <property name="jdbcUrl" value="jdbc:mysql:///bank_transfer"></property>
            <property name="user" value="root"></property>
            <property name="password" value="root"></property>
        </bean>
        <bean id="accountDao" class="pers.zhb.dao.AccountDaoImpl">
            <property name="dataSource" ref="dataSource"></property>
        </bean>
        <bean id="accountService" class="pers.zhb.service.AccountServiceImpl">
            <property name="accountDao" ref="accountDao"></property>
        </bean>
        <!--配置事务管理器-->
        <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
            <property name="dataSource" ref="dataSource"></property>
        </bean>
        <!--将管理器交给spring-->
        <tx:annotation-driven transaction-manager="txManager"></tx:annotation-driven>
    </beans>

    (3)测试类:

    public class Test {
        public static void main(String[] args) {
            ApplicationContext applicationContext=new
                    ClassPathXmlApplicationContext("applicationContext.xml");
            AccountService accountService =(AccountService) applicationContext.getBean("accountService");
            accountService.transfer("zhai","zhang",10);
        }
    }
  • 相关阅读:
    Java文档注释
    Java程序基本框架
    Java文件手动编译执行步骤
    JDK安装中配置Path无效解决办法
    JDK安装配置
    Java简单介绍运行机制
    python代码注释
    python从hello world开始
    python,pycharm,anaconda之间的区别与联系
    python环境配置
  • 原文地址:https://www.cnblogs.com/zhai1997/p/12722124.html
Copyright © 2011-2022 走看看