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

create database spring_transaction;
use spring_transaction;
create table account(
id int primary key auto_increment,
username varchar(50),
money int
);
insert into account(username,money) values('jack',1000);
insert into account(username,money) values('rose',1000);

数据环境

二、无事务下操作数据

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事务学习_测试准备

    在做云笔记项目的过程中,顺便简单的学习了Spring的事务概念,业务以如果添加笔记,则增加用户星星数目作为例子,引入了事务的概念.类似注册送积分之类的,云笔记项目以增加笔记就送星星来说明事务.具体在添 ...

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

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

  3. spring事务学习笔记

    事务管理器 default使用数据库默认的隔离级别

  4. 云笔记项目-Spring事务学习-传播NOT_SUPPORTED

    接下来测试事务传播属性设置为NOT_SUPPORTED Service层 Service层主要设置如下,其中还插入了REQUIRED作为比较. package Service; import java ...

  5. 云笔记项目-Spring事务学习-传播SUPPORTS

    接下来测试事务传播属性SUPPORTS Service层 Service层将方法的事务传播属性设置为SUPPORTS LayerT层代码 package LayerT; import javax.an ...

  6. 云笔记项目-Spring事务学习-传播NEVER

    接下来测试事务传播属性NEVER Service层 Service层中设置事务传播属性都为NEVER. LayerT层代码 package LayerT; import javax.annotatio ...

  7. 云笔记项目-Spring事务学习-传播MANDATORY

    接下来测试事务传播属性MANDATORY Service层 所有Service层实现类都设置事务传播属性为MANDATORY. LayerT层代码 package LayerT; import jav ...

  8. 云笔记项目-Spring事务学习-传播NESTED

    接下来测试事务传播属性NESTED Service层 Service层方法事务传播属性都设置为NESTED. LayerT层代码 package LayerT; import javax.annota ...

  9. 云笔记项目-Spring事务学习-传播REQUIRES_NEW

    接下来测试事务传播的REQUIRES_NEW. Service层 Service层代码在这里不展示了,主要将EMPService1Impl类中的方法事务传播属性设置为REQUIRED,EMPServi ...

随机推荐

  1. .htaccess设置静态资源缓存(即浏览器缓存)

    在HTTP标头中为静态资源设置过期日期或最长存在时间,可指示浏览器从本地磁盘中加载以前下载的资源,而不是通过网络加载.这样, 网站加载速度会更快. 下面的代码都需要放到.htaccess中才能生效. ...

  2. mac基本用法

    1.屏幕截图 command + shift + 4 2.切换到桌面 command + f3 3.右击 双支轻拍 4.彻底退出窗口 command + q 5.关闭窗口 cmd + w 6.隐藏窗口 ...

  3. 微信公众平台JSSDK开发

    根据微信开发文档步骤如下: 1.先登录微信公众平台进入“公众号设置”的“功能设置”里填写“JS接口安全域名”.JS接口安全域名设置 mi.com(前面不用带www/http,域名必须备案过) 2.引入 ...

  4. LeetCode-Count Univalue Subtrees

    Given a binary tree, count the number of uni-value subtrees. A Uni-value subtree means all nodes of ...

  5. MVC5 + EF6 + Bootstrap3 (7) Bootstrap的栅格系统

    文章来源: Slark.NET-博客园http://www.cnblogs.com/slark/p/mvc5-ef6-bs3-get-started-grid.html 上一节:ASP.NET MVC ...

  6. 一个基于.NET平台的自动化/压力测试系统设计简述

    AutoTest系统设计概述 AutoTest是一个基于.NET平台实现的自动化/压力测试的系统,可独立运行于windows平台下,支持分布式部署,不需要其他配置或编译器的支持.(本质是一个基于协议的 ...

  7. JavaScript基础2---控制权DOM操作

    文档对象模型DOM(Document Object Model)定义访问和处理HTML文档的标准方法.DOM将HTML文档呈现为带有元素,属性和文本的树结构(节点树). HTML文档可以说由节点构成的 ...

  8. git点滴的积累

    git的基本学习的网址: http://www.yiibai.com/git/git_update_operation.html 0.git首次上传代码 http://www.cnblogs.com/ ...

  9. js的各种继承

    请先看这个链接:https://segmentfault.com/a/1190000002440502 还有一个里边有js的采用临时方法的继承 http://javapolo.iteye.com/bl ...

  10. ios开发怎么获取输入的日期得到星期

    + (NSString*)weekdayStringFromDate:(NSDate*)inputDate { NSArray *weekdays = [NSArray arrayWithObject ...