zoukankan      html  css  js  c++  java
  • Spring 与 mybatis整合---事务管理

    MyBatis与Spring整合前后事务管理有所区别

    整合前:通过

      session = sessionFactory.openSession(true);  //或者是false

    设置事务是否自动提交;

    整合后,在这样写就不起作用了,无论设置为true还是false  都会自动提交事务;

    如果想设置事务非自动提交有以下几种方案:

      ① 创建session之后,手动拿到connection,设置事务非自动提交

      session.getConnection().setAutoCommit(false);

      ② 通过spring管理事务

        @Test
        /**
         * 测试插入数据,同时测试手动提交事务
         */
        public void test_insert() {
            System.out.println("==============插入数据==================");
            //开启事务
            DefaultTransactionDefinition definition = new DefaultTransactionDefinition();
            DataSourceTransactionManager transactionManager = (DataSourceTransactionManager) DaoApplicationContext
                    .getInstance().getBean("txManager");
            TransactionStatus transactionStatus = (TransactionStatus) transactionManager
                    .getTransaction(definition);
    
            Fh_fullnote order = new Fh_fullnote();
            order.setHf_serialid("HF100120160829155555012507");
            order.setHf_orderid("OD100120160829155555012507");
            order.setCharge_phone("18201304217");
            order.setCharge_money(50D);
            int insertRet = fh_fullnoteDao.insert(order);
            
            //提交事务
            transactionManager.commit(transactionStatus); 
            System.out.println("插入数据返回值:" + insertRet);
        }

      

      ③ 注解式事务

      首先对Dao层做一个详细的解析

      Dao层应用上下文

    package ctp.demo.dao.fh.dao;
    
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    public class DaoApplicationContext {
        private static ApplicationContext ctx=null;
        
        public static ApplicationContext getCtx() {
            return ctx;
        }
        public static void setCtx(ApplicationContext ctx) {
            DaoApplicationContext.ctx = ctx;
        }
        
        
        public static ApplicationContext getInstance(){
            if(ctx == null){
                ctx=new ClassPathXmlApplicationContext("applicationContext-Dao.xml");
            }
            return ctx;
        }
    }
    DaoApplicationContext.java

      Dao数据模型

    package ctp.demo.dao.fh.vo;
    
    import java.util.Date;
    
    public class Fh_fullnote {
        String hf_serialid ;    //流水号
        String hf_orderid ;        //订单号
        Integer isp_id ;        //运营商ID
        Integer province_id;    //省份ID
        Integer city_code;        //城市编码
        Integer service_type;    //业务类型
        String charge_phone;    //充值手机号
        Double charge_money;    //充值金额
        Double finish_money;    //完成金额
        Double charge_flux;        //充值流量
        Double finish_flux;        //完成充值的流量
        Double charge_status;    //充值状态
        Integer error_code ;    //错误码
        String error_info ;        //错误描述
        Date begin_time ;        //开始时间
        Date end_time ;            //结束时间
        String charge_serialid ;//对端流水
        Integer query_count ;    //查询次数
        Integer query_status ;    //查询状态
        Integer notify_flag ;    //通知标识
        Integer notify_count ;    //通知次数
        Integer card_source ;    //卡来源
        String card_num ;        //卡号
        Date charge_datetime ;    //入库时间
        Date query_begintime ;    //查询开始时间
        Integer channel_id ;    //渠道ID
        String card_pwd ;        //卡密
        
        public String getHf_serialid() {
            return hf_serialid;
        }
        public void setHf_serialid(String hf_serialid) {
            this.hf_serialid = hf_serialid;
        }
        public String getHf_orderid() {
            return hf_orderid;
        }
        public void setHf_orderid(String hf_orderid) {
            this.hf_orderid = hf_orderid;
        }
        public Integer getIsp_id() {
            return isp_id;
        }
        public void setIsp_id(Integer isp_id) {
            this.isp_id = isp_id;
        }
        public Integer getProvince_id() {
            return province_id;
        }
        public void setProvince_id(Integer province_id) {
            this.province_id = province_id;
        }
        public Integer getCity_code() {
            return city_code;
        }
        public void setCity_code(Integer city_code) {
            this.city_code = city_code;
        }
        public Integer getService_type() {
            return service_type;
        }
        public void setService_type(Integer service_type) {
            this.service_type = service_type;
        }
        public String getCharge_phone() {
            return charge_phone;
        }
        public void setCharge_phone(String charge_phone) {
            this.charge_phone = charge_phone;
        }
        public Double getCharge_money() {
            return charge_money;
        }
        public void setCharge_money(Double charge_money) {
            this.charge_money = charge_money;
        }
        public Double getFinish_money() {
            return finish_money;
        }
        public void setFinish_money(Double finish_money) {
            this.finish_money = finish_money;
        }
        public Double getCharge_flux() {
            return charge_flux;
        }
        public void setCharge_flux(Double charge_flux) {
            this.charge_flux = charge_flux;
        }
        public Double getFinish_flux() {
            return finish_flux;
        }
        public void setFinish_flux(Double finish_flux) {
            this.finish_flux = finish_flux;
        }
        public Double getCharge_status() {
            return charge_status;
        }
        public void setCharge_status(Double charge_status) {
            this.charge_status = charge_status;
        }
        public Integer getError_code() {
            return error_code;
        }
        public void setError_code(Integer error_code) {
            this.error_code = error_code;
        }
        public String getError_info() {
            return error_info;
        }
        public void setError_info(String error_info) {
            this.error_info = error_info;
        }
        public Date getBegin_time() {
            return begin_time;
        }
        public void setBegin_time(Date begin_time) {
            this.begin_time = begin_time;
        }
        public Date getEnd_time() {
            return end_time;
        }
        public void setEnd_time(Date end_time) {
            this.end_time = end_time;
        }
        public String getCharge_serialid() {
            return charge_serialid;
        }
        public void setCharge_serialid(String charge_serialid) {
            this.charge_serialid = charge_serialid;
        }
        public Integer getQuery_count() {
            return query_count;
        }
        public void setQuery_count(Integer query_count) {
            this.query_count = query_count;
        }
        public Integer getQuery_status() {
            return query_status;
        }
        public void setQuery_status(Integer query_status) {
            this.query_status = query_status;
        }
        public Integer getNotify_flag() {
            return notify_flag;
        }
        public void setNotify_flag(Integer notify_flag) {
            this.notify_flag = notify_flag;
        }
        public Integer getNotify_count() {
            return notify_count;
        }
        public void setNotify_count(Integer notify_count) {
            this.notify_count = notify_count;
        }
        public Integer getCard_source() {
            return card_source;
        }
        public void setCard_source(Integer card_source) {
            this.card_source = card_source;
        }
        public String getCard_num() {
            return card_num;
        }
        public void setCard_num(String card_num) {
            this.card_num = card_num;
        }
        public Date getCharge_datetime() {
            return charge_datetime;
        }
        public void setCharge_datetime(Date charge_datetime) {
            this.charge_datetime = charge_datetime;
        }
        public Date getQuery_begintime() {
            return query_begintime;
        }
        public void setQuery_begintime(Date query_begintime) {
            this.query_begintime = query_begintime;
        }
        public Integer getChannel_id() {
            return channel_id;
        }
        public void setChannel_id(Integer channel_id) {
            this.channel_id = channel_id;
        }
        public String getCard_pwd() {
            return card_pwd;
        }
        public void setCard_pwd(String card_pwd) {
            this.card_pwd = card_pwd;
        }
    }
    Fh_fullnote.java

      Dao操作类

    package ctp.demo.dao.fh.dao;
    
    import java.sql.SQLException;
    import java.util.Map;
    import java.util.TreeMap;
    
    import org.apache.ibatis.session.SqlSession;
    import org.apache.ibatis.session.SqlSessionFactory;
    
    import ctp.demo.dao.fh.vo.Fh_fullnote;
    
    public class Fh_fullnote_dao {
        SqlSession session = null;
        String dao_namespace = "fh.dao.fh_fullnote.";
        /**
         * 订单插入
         * @param order 订单类模型
         * @return 0:插入正常   -1:插入数据异常
         */
        public int insert(Fh_fullnote order){
            try{
                checkSession();
                session.insert(dao_namespace + "addOrder", order);
                return 0;
            }catch(Exception e){
                e.printStackTrace();
                return -1;
            }
        }
        
        /**
         * 根据订单号更新订单状态
         * @param hf_id    订单号
         * @param orderStatus 订单状态
         * @return 0:正常   -1:异常
         */
        public int updateChargeStatusByHF(String hf_id,String orderStatus){
            try{
                checkSession();
                Map<String, String> map = new TreeMap<String, String>();
                map.put("hf_id", hf_id);
                map.put("orderStatus", orderStatus);
                session.update(dao_namespace + "updateChargeStatusByHF", map);
                return 0;
            }catch(Exception e){
                e.printStackTrace();
                return -1;
            }
        }
        
        /**
         * 根据流水号 获取订单
         * @param hf_id 流水号
         * @return 订单 or null
         */
        public Fh_fullnote getOrderByHF_ID(String hf_id){
            try {
                checkSession();
                Fh_fullnote order = (Fh_fullnote)session.selectOne(dao_namespace+"getOrderByHF_ID", hf_id);
                return order;
            } catch (Exception e) {
                // TODO: handle exception
                e.printStackTrace();
                return null;
            }
        }
        
        /**
         * 检查当前是否有session,没有则打开一个session
         */
        public void checkSession(){
            if(session == null){
                SqlSessionFactory sessionFactory = (SqlSessionFactory)DaoApplicationContext.getInstance().getBean("sqlSessionFactory");
                session = sessionFactory.openSession();
                
                try {
                    System.out.println("是否自动提交:" + session.getConnection().getAutoCommit());
                } catch (SQLException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    }
    Fh_fullnote_dao.java

      映射文件

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"   
    "http://mybatis.org/dtd/mybatis-3-mapper.dtd">  
    <mapper namespace="fh.dao.fh_fullnote">
        <!-- 插入数据 -->
        <insert id="addOrder" parameterType="ctp.demo.dao.fh.vo.Fh_fullnote">         
            insert into fh_fullnote ( HF_SERIALID, HF_ORDERID, ISP_ID, PROVINCE_ID, CITY_CODE, SERVICE_TYPE, CHARGE_PHONE, CHARGE_MONEY, FINISH_MONEY, CHARGE_FLUX, FINISH_FLUX, CHARGE_STATUS, ERROR_CODE, ERROR_INFO, BEGIN_TIME, END_TIME, CHARGE_SERIALID, QUERY_COUNT, QUERY_STATUS, NOTIFY_FLAG, NOTIFY_COUNT, CARD_SOURCE, CARD_NUM, CHARGE_DATETIME, QUERY_BEGINTIME, CHANNEL_ID, CARD_PWD) 
                    values(#{hf_serialid},#{hf_orderid},#{isp_id},#{province_id},#{city_code},#{service_type},#{charge_phone},#{charge_money},#{finish_money},#{charge_flux},#{finish_flux},#{charge_status},#{error_code},#{error_info},#{begin_time},#{end_time},#{charge_serialid},#{query_count},#{query_status},#{notify_flag},#{notify_count},#{card_source},#{card_num},#{charge_datetime},#{query_begintime},#{channel_id},#{card_pwd}); 
        </insert>
        
        <!-- 根据流水号修改充值状态 -->
        <update id="updateChargeStatusByHF" parameterType="java.util.Map">
            update fh_fullnote set CHARGE_STATUS = #{orderStatus}
                where HF_SERIALID = #{hf_id}
        </update>
        
        <!-- 根据流水号获取订单 -->
        <select id="getOrderByHF_ID" parameterType="String" resultType = "ctp.demo.dao.fh.vo.Fh_fullnote">
            select * from fh_fullnote where HF_SERIALID = #{hf_id}
        </select>
    </mapper>
    fh_fullnote_mapper.xml

       Spring配置文件

    <?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: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-2.5.xsd 
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd"
        >
        <!--开启注解配置  -->     
        <context:annotation-config />
        <!-- 扫描注解 -->
        <context:component-scan base-package="ctp" />
        <!-- 配置数据源 -->
        <bean id = "dataSource" name="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
            <property name="driverClassName" value="com.mysql.jdbc.Driver" />  
            <property name="url" value="jdbc:mysql://192.168.61.28:3306/ctp" />  
            <property name="username" value="encysys48" />     
            <property name="password" value="encysys48" />
        </bean>
        
        <!-- 配置事务管理器 -->
        <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">  
            <property name="dataSource" ref="dataSource"/>  
        </bean>
        <!-- 事务注解驱动 -->
        <tx:annotation-driven transaction-manager="txManager" /> 
        
        <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
            <!-- 注入mybatis的配置文件 -->
            <property name="configLocation">
                <!-- 不加classpath:会出现错误 -->
                <value>classpath:mybatis-config.xml</value>
            </property>
            <property name="dataSource">
                <!-- 此处填写ID -->
                <ref local="dataSource"/>
            </property>
            <property name="mapperLocations" value="classpath:ctp/**/*mapper.xml">
            </property>
        </bean>
        
        <bean id="Fh_fullnote_dao" class="ctp.demo.dao.fh.dao.Fh_fullnote_dao">
        </bean>
        
         <!-- 自动扫描映射器 -->  
        <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">  
            <property name="basePackage" value="ctp" />  
        </bean>
        
    </beans>
    applicationContext-Dao.xml

      下面看Service层:

    package ctp.demo.service.fh;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Component;
    import org.springframework.transaction.annotation.Transactional;
    
    import ctp.demo.dao.fh.dao.Fh_fullnote_dao;
    import ctp.demo.dao.fh.vo.Fh_fullnote;
    
    @Component("fh_fullnoteService")
    @Transactional
    public class Fh_fullnoteService {
        
        @Autowired
        Fh_fullnote_dao fh_fullnoteDao;
        
        @Transactional(rollbackFor={Exception.class, RuntimeException.class})
        public int addOrder(Fh_fullnote order){
            try {
                int insertRet = fh_fullnoteDao.insert(order);
                System.out.println("下单结果:" + insertRet);
                return 0;
            } catch (Exception e) {
                // TODO: handle exception
                return -1;
            }
        }
        
        public Fh_fullnote_dao getFh_fullnoteDao() {
            return fh_fullnoteDao;
        }
        public void setFh_fullnoteDao(Fh_fullnote_dao fh_fullnoteDao) {
            this.fh_fullnoteDao = fh_fullnoteDao;
        }
    }

      测试代码:  

    package ctp.demo.service.fh;
    
    import static org.junit.Assert.*;
    
    import org.junit.Test;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    import org.springframework.jdbc.datasource.DataSourceTransactionManager;
    import org.springframework.transaction.TransactionStatus;
    import org.springframework.transaction.annotation.Transactional;
    import org.springframework.transaction.support.DefaultTransactionDefinition;
    
    import ctp.demo.dao.fh.dao.DaoApplicationContext;
    import ctp.demo.dao.fh.vo.Fh_fullnote;
    
    public class Test_Fh_fullnoteService {
    
        @Test
        public void test() {
            System.out.println("===============下单开始================");
            
            Fh_fullnote order = new Fh_fullnote();
            order.setHf_serialid("HF100120160829155555012510");
            order.setHf_orderid("OD100120160829155555012510");
            order.setCharge_phone("18201304217");
            order.setCharge_money(50D);
            //关于Dao层的配置文件,需要在service层读取,然后将上下文注入到Dao里面
            //否则的话 @Transactional注解是不生效的
            String[] configeRations = new String[]{"applicationContext-Service.xml","applicationContext-Dao.xml"};
            ApplicationContext ctx=new ClassPathXmlApplicationContext(configeRations);
            DaoApplicationContext.setCtx(ctx);
            Fh_fullnoteService fullnote_service = (Fh_fullnoteService)ctx.getBean("fh_fullnoteService");
            fullnote_service.addOrder(order);
            System.out.println();
        }
    
    }

      通过断点调试,发现跳出函数之前,是不会提交的,说明注解事务生效。

      需要注意的是,Dao层应用的上下文应该与Service应用的上下文一致,那么Dao层的配置文件就应该在Service层读取,然后将上下文注入到Dao层中。

      附配置文件:

    <?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:tx="http://www.springframework.org/schema/tx"
        xsi:schemaLocation="http://www.springframework.org/schema/beans 
        http://www.springframework.org/schema/beans/spring-beans-2.5.xsd 
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd"
        >
        
        <!-- 配置数据源 -->
        <bean id = "dataSource" name="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
            <property name="driverClassName" value="com.mysql.jdbc.Driver" />  
            <property name="url" value="jdbc:mysql://192.168.61.28:3306/ctp" />  
            <property name="username" value="encysys48" />     
            <property name="password" value="encysys48" />
        </bean>
        
        <!-- 配置事务管理器 -->
        <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">  
            <property name="dataSource" ref="dataSource"/>  
        </bean>
        <!-- 事务注解驱动 -->
        <tx:annotation-driven transaction-manager="txManager" /> 
        
        <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
            <!-- 注入mybatis的配置文件 -->
            <property name="configLocation">
                <!-- 不加classpath:会出现错误 -->
                <value>classpath:mybatis-config.xml</value>
            </property>
            <property name="dataSource">
                <!-- 此处填写ID -->
                <ref local="dataSource"/>
            </property>
            <property name="mapperLocations" value="classpath:ctp/**/*mapper.xml">
            </property>
        </bean>
        
        <bean id="Fh_fullnote_dao" class="ctp.demo.dao.fh.dao.Fh_fullnote_dao">
        </bean>
    </beans>
    applicationContext-Dao.xml
    <?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: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-2.5.xsd 
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd"
        >
        
        <!--开启注解配置  -->     
        <context:annotation-config />
        <!-- 扫描注解 -->
        <context:component-scan base-package="ctp" />
        <!-- 注解自动生效 -->
        <bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor" />
        
        
        <bean id="fh_fullnoteDao" class="ctp.demo.dao.fh.dao.Fh_fullnote_dao" />
    </beans>
    applicationContext-Service.xml

        全部源码:http://download.csdn.net/detail/panpanteng/9618044

  • 相关阅读:
    vs 视图其它窗口命令窗口
    WPF 翻转动画实现(转)
    ASP.NET的后台代码和前台JS代码相互调用
    LINQ学习心得分享(三)LINQ语法详解2
    LINQ学习心得分享(二)LINQ语法详解
    《AJAX学习心得分享(三)AJAX+JSON无刷新加载大量后台数据》
    A simple poem
    LINQ学习心得分享(五)LINQ TO SQL实用详解
    LINQ学习心得分享(四)LINQ TO XML实用解析
    AJAX学习心得分享(一)AJAX初识+原生态AJAX
  • 原文地址:https://www.cnblogs.com/tengpan-cn/p/5822133.html
Copyright © 2011-2022 走看看