spring事务学习(转账案例)(一)
一、创建数据库并插入数据
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事务学习(转账案例)(一)的更多相关文章
- 云笔记项目-Spring事务学习_测试准备
在做云笔记项目的过程中,顺便简单的学习了Spring的事务概念,业务以如果添加笔记,则增加用户星星数目作为例子,引入了事务的概念.类似注册送积分之类的,云笔记项目以增加笔记就送星星来说明事务.具体在添 ...
- spring事务学习(转账案例)(二)
四.通过springAop进行事务管理 继续从第一个无事务操作的项目中进行更改. 只修改applicationContext.xml配置文件,注意设置transaction引用 <?xml ve ...
- spring事务学习笔记
事务管理器 default使用数据库默认的隔离级别
- 云笔记项目-Spring事务学习-传播NOT_SUPPORTED
接下来测试事务传播属性设置为NOT_SUPPORTED Service层 Service层主要设置如下,其中还插入了REQUIRED作为比较. package Service; import java ...
- 云笔记项目-Spring事务学习-传播SUPPORTS
接下来测试事务传播属性SUPPORTS Service层 Service层将方法的事务传播属性设置为SUPPORTS LayerT层代码 package LayerT; import javax.an ...
- 云笔记项目-Spring事务学习-传播NEVER
接下来测试事务传播属性NEVER Service层 Service层中设置事务传播属性都为NEVER. LayerT层代码 package LayerT; import javax.annotatio ...
- 云笔记项目-Spring事务学习-传播MANDATORY
接下来测试事务传播属性MANDATORY Service层 所有Service层实现类都设置事务传播属性为MANDATORY. LayerT层代码 package LayerT; import jav ...
- 云笔记项目-Spring事务学习-传播NESTED
接下来测试事务传播属性NESTED Service层 Service层方法事务传播属性都设置为NESTED. LayerT层代码 package LayerT; import javax.annota ...
- 云笔记项目-Spring事务学习-传播REQUIRES_NEW
接下来测试事务传播的REQUIRES_NEW. Service层 Service层代码在这里不展示了,主要将EMPService1Impl类中的方法事务传播属性设置为REQUIRED,EMPServi ...
随机推荐
- C++引用和java引用的区别
在c++里的引用其实是一个变量的别名,而java则是一个变量存储实际对象的地址和C++指针很相似
- 淘宝账号基于OAuth2.0的登录验证授权登陆第三方网站
首先得有一个注册的appkey和App Secret 该流程分三个步骤: 第一步:通过用户授权获取授权码Code: 第二步:用上一步获取的Code和应用密钥(AppSecret)通过Https P ...
- 基于.Net FrameWork的 RestFul Service
关于本文 这篇文章的目的就是向大家阐述如何在.net framework 4.0中创建RestFul Service并且使用它. 什么是web Services,什么是WCF 首先讲到的是web Se ...
- [CareerCup] 4.5 Validate Binary Search Tree 验证二叉搜索树
4.5 Implement a function to check if a binary tree is a binary search tree. LeetCode上的原题,请参见我之前的博客Va ...
- Javascript的字面量对象以及如何拆解字面量对象
简单的说,字面量对象提供了一直非常方便构建新对象的方式,它的格式非常简单且容易阅读.是大多数前端程序员在构建对象时比较推崇的一种方式. 格式: var person = { name : " ...
- 傻傻分不清楚的php脚本路径
闲话就不说了,还是直接提出今天的问题,准确的说,对多个相似的 有关当前脚本信息的全局变量常量的区分. 先贴上代码: <?php echo $_SERVER['PHP_SELF']; echo ...
- ORCHARD中文文档(翻译)
众所周知,Orchard是.net领域最好的开源CMS之一,他使用了微软最先进的技术,有一群先进理念的支持者,但是,所有的事情在国内总得加个但是,Orchard也不例外,中文资料相对比较少,官网提供的 ...
- IE10访问apache 2.4会奇慢的解决办法
Windows版的apache 2.4. IE10访问apache 2.4会特别慢.有时Apache挂起了.只好重新开apache,但是重开后,也会好景不长,刚处理几个请求,就又变得奇慢了.Firef ...
- Unity 3D本地发布WebPlayer版时Failed to download data file解决方案
遇到这个问题就是指Web服务器并没有支持这种*.unity3d文件类型.需要做的是在Web服务器中添加MIME类型: IIS 7 及以上版本: 在功能视图的IIS选项卡中: 双击打开MIME,选择添加 ...
- JavaScript基础---语言基础(3)
流程控制语句 学习要点: 1.switch语句 2.for...in语句 3.break和continue语句 4.with语句 ECMA-262规定了一组流程控制语句.语句定义了ECMAScript ...