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

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. Scrapy 爬虫 使用指南 完全教程

    scrapy note command 全局命令: startproject :在 project_name 文件夹下创建一个名为 project_name 的Scrapy项目. scrapy sta ...

  2. 循环队列java实现

    public class SeqHeap { Object[] data; int font; int rear; int maxSize; public SeqHeap(int maxSize) { ...

  3. PSR-1:基本的代码风格

    PHP标签 必须把PHP代码放在<?php ?>或<?= ?>标签中.不得使用其他PHP标签句法. 编码 所有PHP文件都必须使用UTF-8字符集编码,而且不能有字节顺序标记( ...

  4. XSHELL使用隧道

    线上系统中,搭建了一个elasticsearch环境,想要访问页面,发现环境的内网中没有windows机器,无法使用浏览器来直接进行web页面的访问,于是直接使用了XSELL中强大的功能"隧 ...

  5. 【Mocha.js 101】钩子函数

    前情提要 在上一篇文章<[Mocha.js 101]同步.异步与 Promise>中,我们学会了如何对同步方法.异步回调方法以及 Promise 进行测试. 在本篇文章中,我们将了解到 M ...

  6. IOS开发常用设计模式

    IOS开发常用设计模式 说起设计模式,感觉自己把握不了笔头,所以单拿出iOS开发中的几种常用设计模式谈一下. 单例模式(Singleton) 概念:整个应用或系统只能有该类的一个实例 在iOS开发我们 ...

  7. linux shell的切换

    查看系统可用shell种类:(一般是bash shell) ➜ ~ chsh -l /bin/sh /bin/bash /sbin/nologin /bin/dash /bin/zsh 修改当前的sh ...

  8. Bzoj 4408: [Fjoi 2016]神秘数 可持久化线段树,神题

    4408: [Fjoi 2016]神秘数 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 177  Solved: 128[Submit][Status ...

  9. 『SQL注入』 User-Agent 手工注入的探测与利用分析

    原理很简单:后台在接收UA时没有对UA做过滤,也没有PDO进行数据交互(实际PDO是非常有必要的),导致UA中有恶意代码,最终在数据库中执行. Bug 代码: 本地顺手打了一个环境,Bug 代码部分: ...

  10. Linux下添加磁盘创建lvm分区

    shell> fdisk /dev/xvdb #### 选择磁盘 Command (m for help): m #### 帮助 Command action a toggle a bootab ...