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

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. 【转】【C#】C#重绘windows窗体标题栏和边框

    摘要 windows桌面应用程序都有标准的标题栏和边框,大部分程序也默认使用这些样式,一些对视觉效果要求较高的程序,如QQ, MSN,迅雷等聊天工具的样式则与传统的windows程序大不相同,其中迅雷 ...

  2. SQLServer 语句-创建索引

    语法:CREATE [索引类型] INDEX 索引名称ON 表名(列名)WITH FILLFACTOR = 填充因子值0~100GO /*实例*/USE 库名GOIF EXISTS (SELECT * ...

  3. 经典趣味24点游戏程序设计(python)

    一.游戏玩法介绍: 24点游戏是儿时玩的主要益智类游戏之一,玩法为:从一副扑克中抽取4张牌,对4张牌使用加减乘除中的任何方法,使计算结果为24.例如,2,3,4,6,通过( ( ( 4 + 6 ) - ...

  4. Spring4 MVC文件下载实例

    这篇文章将向您展示如何使用Spring MVC4执行文件下载,我们将看到应用程序从文件系统内部以及外部文件下载文件. 本教程的主要亮点: 下载文件是相当简单的,涉及以下步骤. 创建一个InputStr ...

  5. Linux第14周学习笔记

    虚拟存储器 虚拟存储器是硬件异常.硬件地址翻译.主存.磁盘文件和内核软件的完美交互. 虚拟存储器的特点: 中心的 强大的 危险的 物理和虚拟寻址 计算机系统的主存被组织成一个由M个连续的字节大小的单元 ...

  6. Ubuntu驱动摄像头

    之前研究Opencv的时候是安装了一个virtualbox的虚拟机,然后发现电脑自带的摄像头无法被识别. 后来买了一个罗技的C270,仍然无法识别,而且插入到虚拟机之后会导致虚拟机死机,原因未知. - ...

  7. C#出题库项目的总结(1)

    前记: 截止18点05分(4月9号),完成了代码部分的编写,明天争取把文档完成,毕竟在这个上面花的时间太多了,还有单词和书需要背,好吧,不说废话啦,下面进入正题. (PS:因为学院的模拟招聘笔试出题和 ...

  8. try-catch和throw,throws的区别和联系

    转载:http://blog.sina.com.cn/s/blog_62148d1e0100hkqc.html 区别一:throw 是语句抛出一个异常:throws 是方法抛出一个异常: throw语 ...

  9. C#异步编程一

    前几天把Code First系列总结完,想着下步总结什么,原本想着XML,不过XML的内容比较多,还有3天班就中秋节了,想在中秋节前在完成一个系列,所以决定把异步这块总结下.说起异步可能会认为就是多线 ...

  10. [BZOJ 2456]Mode(神奇的抵销)

    题意:求一串数的众数(保证次数的出现次数超过一半),n<=500000 很简单是不是……快拍一下不就行了吗,不超时呢=W=,不过……尼玛空间只有1M…… 于是此题就成了神题(理解成智商题= =本 ...