Spring 与 mybatis整合---事务管理

时间:2022-12-29 18:30:46

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

Spring 与 mybatis整合---事务管理的更多相关文章

  1. SpringMVC&plus;MyBatis整合——事务管理

    项目一直没有做事务管理,这几天一直在想着解决这事,今天早上终于解决了.接下来直接上配置步骤. 我们项目采用的基本搭建环境:SpringMVC.MyBatis.Oracle11g.WebLogic10. ...

  2. spring与hibernate整合事务管理的理解

    在谈Spring事务管理之前我们想一下在我们不用Spring的时候,在Hibernate中我们是怎么进行数据操作的.在Hibernate中我们每次进行一个操作的的时候我们都是要先开启事务,然后进行数据 ...

  3. Spring Transaction &plus; MyBatis SqlSession事务管理机制&lbrack;marked&rsqb;

  4. Spring Boot -- Spring Boot之&commat;Async异步调用、Mybatis、事务管理等

    这一节将在上一节的基础上,继续深入学习Spring Boot相关知识,其中主要包括@Async异步调用,@Value自定义参数.Mybatis.事务管理等. 本节所使用的代码是在上一节项目代码中,继续 ...

  5. spring boot配置mybatis和事务管理

    spring boot配置mybatis和事务管理 一.spring boot与mybatis的配置 1.首先,spring boot 配置mybatis需要的全部依赖如下: <!-- Spri ...

  6. Spring&plus;springmvc&plus;Mybatis整合案例 xml配置版(myeclipse)详细版

    Spring+springmvc+Mybatis整合案例 Version:xml版(myeclipse) 文档结构图: 从底层开始做起: 01.配置web.xml文件 <?xml version ...

  7. Mybatis学习--spring和Mybatis整合

    简介 在前面写测试代码的时候,不管是基于原始dao还是Mapper接口开发都有许多的重复代码,将spring和mybatis整合可以减少这个重复代码,通过spring的模板方法模式,将这些重复的代码进 ...

  8. SpringMVC&comma; Spring和Mybatis整合案例一

    一  准备工作 包括:spring(包括springmvc).mybatis.mybatis-spring整合包.数据库驱动.第三方连接池. 二  整合思路 Dao层: 1.SqlMapConfig. ...

  9. Spring boot Mybatis 整合

    PS: 参考博客 PS: spring boot配置mybatis和事务管理 PS: Spring boot Mybatis 整合(完整版)   这篇博客里用到了怎样 生成 mybatis 插件来写程 ...

随机推荐

  1. iOS UIPageViewController

    UIPageViewController是App中常用的控制器.它提供了一种分页效果来显示其childController的View.用户可以通过手势像翻书一样切换页面.切换页面时看起来是连续的,但静 ...

  2. 用python来调试网络程序

    需要联调的程序,沟通联调起来总是各种麻烦,如果自己能写个简单一点的“测试机”,事情就很easy了:或者有时候想做“中间人”,看看网路上到底传些什么.前面写了串口的测试机,今天尝试了一下UDP的. im ...

  3. PHP面向对象常见的关键字和魔术方法

    在PHP5的面向对象程序设计中提供了一些常见的关键字,用来修饰类.成员属性或成员方法,使他们具有特定的功能,例如final.static.const等关键字.还有一些比较实用的魔术方法,用来提高类或对 ...

  4. 第一部分:使用iReport制作报表的详细过程(Windows环境下)

    提示:在有些板块,文中的图片看不到,建议到我的blog浏览文章:http://blog.csdn.net/jemlee2002/文章将会涉及3个方面的内容: 第一部分:使用iReport制作报表的详细 ...

  5. C语言 复杂的栈(链表栈)

    //复杂的栈--链表栈 #include<stdio.h> #include<stdlib.h> #define datatype int//定义链表栈数据类型 //定义链表栈 ...

  6. sql从某不连续的数字中将其分段并找出缺失的数字并分段

    首先做准备数据 )) ') ') ') ') ') ') ') ') ') ') ') ') ') ') ') ') 将数据转换成应该处理的数据格式 ),colValue INT ) ) ,LEN(c ...

  7. ObjectiveC中的block用法解析

    Block Apple 在C, Objective-C,C++加上Block这个延申用法.目前只有Mac 10.6 和iOS 4有支持.Block是由一堆可执行的程序组成,也可以称做没有名字的Func ...

  8. Hyperledger Fabric 1&period;0 从零开始(七)——启动Fabric多节点集群

    5:启动Fabric多节点集群 5.1.启动orderer节点服务 上述操作完成后,此时各节点的compose配置文件及证书验证目录都已经准备完成,可以开始尝试启动多机Fabric集群. 首先启动or ...

  9. Codeforces-542div2

    https://www.cnblogs.com/31415926535x/p/10468017.html codeforces-1130A~G 和队友做了一套题,, A. Be Positive 题意 ...

  10. 20145201 《Java程序设计》第四周学习总结

    20145201 <Java程序设计>第四周学习总结 教材学习内容总结 本周学习了课本第六.七章内容,即继承与多态.接口与多态. 第六章 继承与多态 6.1 何谓继承 6.1.1 继承共同 ...