一、创建数据库并插入数据

create database spring_transaction;
use spring_transaction;
create table account(
id int primary key auto_increment,
username ),
money int
);
);
);

数据环境

二、无事务下操作数据

1、项目结构及引用的相应jar包

2、创建接口AccountDao及其实现类AccountDaoImpl(实现类继承自JdbcDaoSupport,可以直接获得jdbc模板对象)

package com.hujp.dao;

/**
 * Created by JiaPeng on 2015/11/4.
 */
public interface AccountDao {
    /**
     * 收款(入)
     * @param inUser
     * @param money
     */
    public void in(String inUser,int money);

    /**
     * 汇款(出)
     * @param outUser
     * @param money
     */
    public void out(String outUser,int money);
}

AccountDao

package com.hujp.dao.impl;

import com.hujp.dao.AccountDao;
import org.springframework.jdbc.core.support.JdbcDaoSupport;

/**
 * Created by JiaPeng on 2015/11/4.
 */
public class AccountDaoImpl extends JdbcDaoSupport implements AccountDao {

    @Override
    public void in(String inUser, int money) {
        this.getJdbcTemplate().update("UPDATE account SET money=money+? WHERE username=?",money,inUser);
    }

    @Override
    public void out(String outUser, int money) {
        this.getJdbcTemplate().update("UPDATE account SET money=money-? WHERE username=?", money, outUser);
    }
}

AccountDaoImpl

3、创建接口AccountService及其实现类AccountServiceImpl(实现类里需要有AccountDao字段,在spring配置中注入)

package com.hujp.service;

/**
 * Created by JiaPeng on 2015/11/4.
 */
public interface AccountService {
    public void transfer(String outUser,String inUser,int money);
}

AccountService

package com.hujp.service.impl;

import com.hujp.dao.AccountDao;
import com.hujp.service.AccountService;

/**
 * Created by JiaPeng on 2015/11/4.
 */
public class AccountServiceImpl implements AccountService {

    private AccountDao accountDao;

    public void setAccountDao(AccountDao accountDao) {
        this.accountDao = accountDao;
    }

    @Override
    public void transfer(String outUser, String inUser, int money) {
        this.accountDao.out(outUser, money);
        //模拟断电
        //int m=2/0;
        this.accountDao.in(inUser, money);
    }
}

AccountServiceImpl

4、配置文件applicationContext.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:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
                           http://www.springframework.org/schema/beans/spring-beans.xsd
                           http://www.springframework.org/schema/context
                           http://www.springframework.org/schema/context/spring-context.xsd
                           http://www.springframework.org/schema/aop
                           http://www.springframework.org/schema/aop/spring-aop.xsd">
       <!--配置数据源-->
       <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
           <property name="driverClass" value="com.mysql.jdbc.Driver"></property>
           <property name="jdbcUrl" value="jdbc:mysql:///spring_transaction"></property>
           <property name="user" value="root"></property>
           <property name="password" value="hjp123"></property>
       </bean>
       <!--配置Dao-->
       <bean id="accountDao" class="com.hujp.dao.impl.AccountDaoImpl">
           <property name="dataSource" ref="dataSource"></property>
       </bean>
       <!--配置Service-->
       <bean id="accountService" class="com.hujp.service.impl.AccountServiceImpl">
              <property name="accountDao" ref="accountDao"></property>
       </bean>
</beans>

applicationContext

package com.hujp;

import com.hujp.service.AccountService;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * Created by JiaPeng on 2015/11/4.
 */
public class TestApp {
    @Test
    public void demo1() {
        String xmlPath = "applicationContext.xml";
        ApplicationContext applicationContext=new ClassPathXmlApplicationContext(xmlPath);
        AccountService accountService= (AccountService) applicationContext.getBean("accountService");
        accountService.transfer("jack","rose",100);
    }
}

测试类

5、代码结构图

二、手动操作事务管理数据库

事务管理主要在service层,所以需要改动两个文件即可,一个是application配置文件,另一个是AccountServiceImpl实现类

在实现类中,事务模板对象执行execute方法,重写事务返回无结果集抽象类TransactionCallbackWithoutResult的抽象方法doInTransactionWithoutResult达到事务管理目的

package com.hujp.service.impl;

import com.hujp.dao.AccountDao;
import com.hujp.service.AccountService;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;

/**
 * Created by JiaPeng on 2015/11/4.
 */
public class AccountServiceImpl implements AccountService {

    private AccountDao accountDao;

    public void setAccountDao(AccountDao accountDao) {
        this.accountDao = accountDao;
    }

    //事务操作一般在service层进行操作
    private TransactionTemplate transactionTemplate;

    public void setTransactionTemplate(TransactionTemplate transactionTemplate) {
        this.transactionTemplate = transactionTemplate;
    }

    @Override
    public void transfer(final String outUser,final String inUser, final int money) {

        //无结果集操作
        this.transactionTemplate.execute(new TransactionCallbackWithoutResult() {
            @Override
            protected void doInTransactionWithoutResult(TransactionStatus transactionStatus) {
                accountDao.out(outUser, money);
                //模拟断电
                //int m=2/0;
                accountDao.in(inUser, money);
            }
        });
    }
}

AccountServiceImpl

<?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:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
                           http://www.springframework.org/schema/beans/spring-beans.xsd
                           http://www.springframework.org/schema/context
                           http://www.springframework.org/schema/context/spring-context.xsd
                           http://www.springframework.org/schema/aop
                           http://www.springframework.org/schema/aop/spring-aop.xsd">
    <!--配置数据源-->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass" value="com.mysql.jdbc.Driver"></property>
        <property name="jdbcUrl" value="jdbc:mysql:///spring_transaction"></property>
        <property name="user" value="root"></property>
        <property name="password" value="hjp123"></property>
    </bean>
    <!--配置Dao-->
    <bean id="accountDao" class="com.hujp.dao.impl.AccountDaoImpl">
        <property name="dataSource" ref="dataSource"></property>
    </bean>
    <!--配置Service-->
    <bean id="accountService" class="com.hujp.service.impl.AccountServiceImpl">
        <property name="accountDao" ref="accountDao"></property>
        <!--一般事务操作在service层进行,所以在service层注入模板-->
        <property name="transactionTemplate" ref="transactionTemplate"></property>
    </bean>
    <!--事务管理要提供事务管理器,事务是从数据库连接中获得的,而数据库连接是从连接池中获得的-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"></property>
    </bean>
    <!--提供事务模板,事务模板要在平台上进行事务操作-->
    <bean id="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate">
        <property name="transactionManager" ref="transactionManager"></property>
    </bean>
</beans>

applicationContext.xml

三、使用工厂bean创建代理管理事务

继续使用无事务下操作数据库的工程,测试类中accountService对象由代理类创建,并在配置文件配置工厂bean内配置事务

主要改两个文件,一个是测试类,其中获得service对象通过工厂bean获得;另一个是在applicationContext.xml文件中配置工厂bean和事务操作

package com.hujp;

import com.hujp.service.AccountService;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * Created by JiaPeng on 2015/11/4.
 */
public class TestApp {
    @Test
    public void demo1() {
        String xmlPath = "applicationContext.xml";
        ApplicationContext applicationContext=new ClassPathXmlApplicationContext(xmlPath);
        AccountService accountService= (AccountService) applicationContext.getBean("proxyService");
        accountService.transfer("jack","rose",100);
    }
}

测试类

<?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:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
                           http://www.springframework.org/schema/beans/spring-beans.xsd
                           http://www.springframework.org/schema/context
                           http://www.springframework.org/schema/context/spring-context.xsd
                           http://www.springframework.org/schema/aop
                           http://www.springframework.org/schema/aop/spring-aop.xsd">
    <!--配置数据源-->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass" value="com.mysql.jdbc.Driver"></property>
        <property name="jdbcUrl" value="jdbc:mysql:///spring_transaction"></property>
        <property name="user" value="root"></property>
        <property name="password" value="hjp123"></property>
    </bean>
    <!--配置Dao-->
    <bean id="accountDao" class="com.hujp.dao.impl.AccountDaoImpl">
        <property name="dataSource" ref="dataSource"></property>
    </bean>
    <!--配置Service(目标类)-->
    <bean id="accountService" class="com.hujp.service.impl.AccountServiceImpl">
        <property name="accountDao" ref="accountDao"></property>
    </bean>
    <!--创建service代理对象之后使用的是代理对象-->
    <bean id="proxyService" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
        <!--确定事务管理器-->
        <property name="transactionManager" ref="transactionManager"></property>
        <!--确定接口-->
        <property name="proxyInterfaces" value="com.hujp.service.AccountService"></property>
        <!--确定目标类-->
        <property name="target" ref="accountService"></property>
        <!--配置事务属性(事务详情)-->
        <property name="transactionAttributes">
            <!--
                prop.key 表示事务详情名称,用于指定哪些方法使用设置的详情
                比如目标类中的transfer方法
                如果是add*,表示以add开头的方法;如果是*表示任意方法
                prop.text 表示当前方法使用具体详情设置
                    格式:PROPAGATION,ISOLATION,readOnly,-Exception,+Exception
                          传播行为     隔离级别   是否只读 异常回滚   异常提交
                例如:PROPAGATION_REQUIRED,ISOLATION_REPEATABLE_READ表示默认的传播行为和隔离级别
                      PROPAGATION_REQUIRED,ISOLATION_REPEATABLE_READ,readOnly表示只读
                      java.lang.ArithmeticException此异常是在断电程序中出现的
                      PROPAGATION_REQUIRED,ISOLATION_REPEATABLE_READ,+java.lang.ArithmeticException表示异常提交
            -->
            <props>
                <!--<prop key="transfer">PROPAGATION_REQUIRED,ISOLATION_REPEATABLE_READ</prop>
                <prop key="transfer">PROPAGATION_REQUIRED,ISOLATION_REPEATABLE_READ,readOnly</prop>-->
                <prop key="transfer">PROPAGATION_REQUIRED,ISOLATION_REPEATABLE_READ,+java.lang.ArithmeticException</prop>
            </props>
        </property>
    </bean>
    <!--管理器-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"></property>
    </bean>

</beans>

applicationContext

spring事务学习(转账案例)(一)的更多相关文章

  1. spring事务学习(转账案例)(二)

    四.通过springAop进行事务管理 继续从第一个无事务操作的项目中进行更改. 只修改applicationContext.xml配置文件,注意设置transaction引用 <?xml ve ...

  2. spring事务管理学习

    spring事务管理学习 spring的事务管理和mysql自己的事务之间的区别 参考很好介绍事务异常回滚的文章 MyBatis+Spring 事务管理 spring中的事务回滚例子 这篇文章讲解了@ ...

  3. 【Java EE 学习 52】【Spring学习第四天】【Spring与JDBC】【JdbcTemplate创建的三种方式】【Spring事务管理】【事务中使用dbutils则回滚失败!!!??】

    一.JDBC编程特点 静态代码+动态变量=JDBC编程. 静态代码:比如所有的数据库连接池 都实现了DataSource接口,都实现了Connection接口. 动态变量:用户名.密码.连接的数据库. ...

  4. spring分布式事务学习笔记

    最近项目中使用了分布式事务,本文及接下来两篇文章总结一下在项目中学到的知识. 分布式事务对性能有一定的影响,所以不是最佳的解决方案,能通过设计避免最好尽量避免. 分布式事务(Distributed t ...

  5. 【原】Spring和Dubbo整合案例和过程

    Dubbo是Alibaba开源的分布式服务框架,它最大的特点是按照分层的方式来架构,使用这种方式可以使各个层之间解耦合(或者最大限度地松耦合).从服务模型的角度来看,Dubbo采用的是一种非常简单的模 ...

  6. Spring 事务管理笔记

    本文为 Spring 框架的事务管理学习笔记,官网文档地址为:Transaction Management,隔离级别及传播属性解释来自 org.springframework.transaction. ...

  7. Spring事务管理

    Spring是SSH中的管理员,负责管理其它框架,协调各个部分的工作.今天一起学习一下Spring的事务管理.Spring的事务管理分为声明式跟编程式.声明式就是在Spring的配置文件中进行相关配置 ...

  8. Spring事务管理(转)

    Spring是SSH中的管理员,负责管理其它框架,协调各个部分的工作.今天一起学习一下Spring的事务管理.Spring的事务管理分为声明式跟编程式.声明式就是在Spring的配置文件中进行相关配置 ...

  9. Spring+springmvc+Mybatis整合案例 annotation版(myeclipse)详细版

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

随机推荐

  1. java文档注释--javadoc的用法

    1.前言 Java中有三种注释方式.前两种分别是 // 和 /* */,主要用于代码的注释,以此来方便代码的可读性.第三种被称作说明注释或文档注释,它以 /** 开始,以 */结束,文档注释允许你在程 ...

  2. 体验Rabbitmq强大的【优先级队列】之轻松面对现实业务场景

    说到队列的话,大家一定不会陌生,但是扯到优先级队列的话,还是有一部分同学是不清楚的,可能是不知道怎么去实现吧,其实呢,,,这东西已 经烂大街了...很简单,用“堆”去实现的,在我们系统中有一个订单催付 ...

  3. jquery基础

    show() hide() toggle()         fadeIn() fadeOut() fadeToggle() fadeTo()         slideUp() slideDown( ...

  4. Echarts 饼图标题文字换行问题

    var option = { title : { text: '数据来源', x:'center' }, tooltip : { trigger: 'item', formatter: "{ ...

  5. windows命令——taskmgr 1

    taskmgr.exe用于任务管理器.它显示系统中正在运行的进程. 该程序使用Ctrl+Alt+Del(一般是弹出Windows安全再点击“任务管理器”)或者Ctrl+Shift+Esc 有时候需要, ...

  6. JSPatch

    链接: JSPatch github项目主页 JSPatch技术文档 JSPatch基础用法总结 JSPatch – 动态更新iOS APP JSPatch使用小记 end

  7. Evolution项目(1)

    Evolution项目是基于NFine修改的项目 主要改动为: 支持了.net core 1.0 支持了 EF core 1.0 支持数据库自动创建及Demo数据自动灌入 修改了授权方式 新增加了一个 ...

  8. Only MySqlParameter objects may be stored

    Only MySqlParameter objects may be stored 今天碰到了这个问题琢磨了半天,最后发现是MySql.Data.dll版本问题,换了个最新版本的就可以了.

  9. 调Windows 7的图片浏览器查看图片

    public static void viewPicFromWindows(string pPicPath) { if (pPicPath!="" && Syste ...

  10. JS JQuery初始化

    (function($) {})(jQuery); 这种写法,申明一个匿名函数并立即调用 $(document).ready(function(){}); 文档全部加载完再执行 等同于$(functi ...