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#】在 Windows 窗体 DataGridView 单元格中承载控件
using System; using System.Windows.Forms; public class CalendarColumn : DataGridViewColumn { public ...
- tee命令
tee命令 http://liubin.blog.51cto.com/282313/131298 https://en.wikipedia.org/wiki/Tee_(command)
- linux输入输出重定向
http://www.cnblogs.com/chengmo/archive/2010/10/20/1855805.html 在Linux下,当一个用户进程被创建的时候,系统会自动为该进程创建三个数据 ...
- MSMQ消息队列安装
一.Windows 7安装.管理消息队列1.安装消息队列 执行用户必须要有本地 Administrators 组中的成员身份,或等效身份. 具体步骤: 开始—>控制面板—>程 ...
- ASP.Net MVC如何访问的静态页面
MVC开发中,因为View文件夹下的web.config文件默认会把任何方法的请求的任何文件,路径都交给 System.Web.HttpNotFoundHandler 去处理.起到Controller ...
- Asp.net设计模式笔记之三:业务逻辑层的组织
本章内容要点: 1.Transaction Script模式组织业务逻辑 2.Active Record模式和Castle Windsor来组织业务逻辑 3.Domain Model模式来组织业务逻辑 ...
- 集中式版本控制系统:从svn到tfs
06年进公司的时候,我们没有使用版本控制系统,所有代码都在部门经理的电脑上放着,谁要改什么代码就过去要一份最新的,改好之后再放回去,感觉好原始.据说之前是用过一段时间微软的vss(visual.sou ...
- java并发:中断一个正在运行的线程
要使任务和线程能安全可靠地停止,并不是一件很容易的事情,java没有提供任何机制来安全地终止线程,那么我们该怎么办呢? 下面我们先来了解一下java中的中断机制: java中断机制是一种协作机制,也就 ...
- Fiddler工具的基本功能
Fiddler是一款用于网页数据分析,抓取的工具,里面集成了对网页强大的功能外,还可以通过设置,使其对手机的数据也可以进行抓取 Fiddler的原理是: 通过在客户端和服务器之间创建一个代理服务器来对 ...
- SSRS用自定义对象绑定报表
有一个报表的数据源是一个对象的List, 这个对象List中还有层级,其中还有其他的对象List,这样的层级有三层.其数据是从数据库中取出来的.其LINQ的操作太多了而且复杂,所以不太可 能从LINQ ...