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+MyBatis整合——事务管理

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

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

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

  3. Spring Transaction + MyBatis SqlSession事务管理机制[marked]

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

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

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

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

  6. Spring+springmvc+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, 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. JS面向对象基础1

    根据之前看了面向对象相关的视频,按照自己的理解,整理出相关的笔记,以便自己的深入理解.     如果要判断两个数是否相等,将值乘以10或者100,转换成整数再进行比较 例如:a++与++a 短路运算符 ...

  2. Animate.css让添加CSS动画像喝水一样容易

    在这个年代,你要是不懂一点点css3的知识,你都不好意思说你是个美工.美你妹啊,请叫我前端工程师好不好.呃..好吧,攻城尸...呵呵,作为一个攻城尸,没有点高端大气上档次的东西怎么能行呢,那么css3 ...

  3. INSTALL_FAILED_NO_MATCHING_ABIS

    在运行写好的cocos的demo时候,安装出现以下问题: 后来发现是因为自己用cygwin生成的x86的.so文件跟自己的魅族3机器CPU不适配!!! 参考:http://stackoverflow. ...

  4. Windows系统顽固文件删除方法

    con nul都是windows的设备,默认是不允许删除的,如果你一定要删除,可以按照以下方法进行删除!新建一个记事本输入一下内容(直接复制即可)DEL /F /A /Q \\?\%1 RD /S / ...

  5. ocean所用的蝴蝶纹理

    #include <ork/render/FrameBuffer.h> #include <ork/scenegraph/SceneManager.h> #include &l ...

  6. Docker私有仓库3

    http://www.cnblogs.com/womars/p/5906435.html(上篇地址) 三.测试上两篇 #测试一下 [root@lh- data]# pwd /opt/data [roo ...

  7. CDOJ 1270 Playfair(模拟)

    题目链接 Playfair is a kind of substitution cipher.And the encryption role is simple.In general,there ar ...

  8. 不完善的css怦然心动,有待改进...

    <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title&g ...

  9. Openjudge-计算概论(A)-字符串排序

    描述 参考整数排序方法,设计一种为字符串排序的算法,将字符串从小到大输出 输入 第一行为测试数据组数t, 后面跟着t组数据.每组数据第一行是n,表示这组数据有n行字符串,接下来是要排序的n行字符串.每 ...

  10. EXEC 和 SP_EXECUTESQL的区别

    摘要: MSSQL为我们提供了两种动态执行sql语句的命令:EXEC 和 SP_EXECUTESQL.通常SP_EXECUTESQL更具优势,因为它提供了输入输出的接口,且能够重用执行计划,大大提高执 ...