峰Spring4学习(8)spring对事务的支持
一、事务简介:
二、编程式事务管理:
例子
1、需求:模拟转账,张三向李四转账50元;
数据库中存在t_count表:
代码实现:
BankDao.java:
package com.cy.dao; public interface BankDao {
//转入money元
public void inMoney(int money,int userId); //转出money元
public void outMoney(int money,int userId);
}
BankDaoImpl.java:
package com.cy.dao.impl; import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; import com.cy.dao.BankDao; public class BankDaoImpl implements BankDao { private NamedParameterJdbcTemplate namedParameterJdbcTemplate; public void setNamedParameterJdbcTemplate(NamedParameterJdbcTemplate namedParameterJdbcTemplate) {
this.namedParameterJdbcTemplate = namedParameterJdbcTemplate;
} //userId转入money元
@Override
public void inMoney(int money, int userId) {
String sql = "update t_count set count = count + :money where userId = :userId";
MapSqlParameterSource sps = new MapSqlParameterSource();
sps.addValue("money", money)
.addValue("userId", userId);
namedParameterJdbcTemplate.update(sql, sps);
} //userId转出money元
@Override
public void outMoney(int money, int userId) {
String sql = "update t_count set count = count - :money where userId = :userId";
MapSqlParameterSource sps = new MapSqlParameterSource();
sps.addValue("money", money)
.addValue("userId", userId);
namedParameterJdbcTemplate.update(sql, sps);
} }
BankService.java:
package com.cy.service; public interface BankService { /**
* A向B转账count元
* @param count
* @param userIdA
* @param userIdB
*/
public void transferAccounts(int count, int userIdA, int userIdB);
}
BankServiceImpl.java:
package com.cy.service.impl; import com.cy.dao.BankDao;
import com.cy.service.BankService; public class BankServiceImpl implements BankService { private BankDao bankDao; public void setBankDao(BankDao bankDao) {
this.bankDao = bankDao;
} //A向B转账count元
@Override
public void transferAccounts(int count, int userIdA, int userIdB) {
bankDao.outMoney(count, userIdA);
bankDao.inMoney(count, userIdB);
} }
beans.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:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd"> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${jdbc.driverClassName}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean> <context:property-placeholder location="jdbc.properties"/> <bean id="namedParameterJdbcTemplate" class="org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate">
<constructor-arg ref="dataSource"></constructor-arg>
</bean> <bean id="bankDao" class="com.cy.dao.impl.BankDaoImpl">
<property name="namedParameterJdbcTemplate" ref="namedParameterJdbcTemplate"></property>
</bean> <bean id="bankService" class="com.cy.service.impl.BankServiceImpl">
<property name="bankDao" ref="bankDao"></property>
</bean> </beans>
测试代码:
package com.cy.test; import org.junit.Before;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; import com.cy.service.BankService; public class T {
private ApplicationContext ac; @Before
public void setUp() throws Exception {
ac=new ClassPathXmlApplicationContext("beans.xml");
} //测试代码
@Test
public void transferAccounts() {
BankService bankService = (BankService)ac.getBean("bankService");
bankService.transferAccounts(50, 1, 2);
} }
将上面代码修改为如下:
1)BankDaoImpl.java中构建t_count2不存在,无法完成转入,会抛出异常:
//userId转入money元
@Override
public void inMoney(int money, int userId) {
String sql = "update t_count2 set count = count + :money where userId = :userId";
MapSqlParameterSource sps = new MapSqlParameterSource();
sps.addValue("money", money)
.addValue("userId", userId);
namedParameterJdbcTemplate.update(sql, sps);
}
2)BankServiceImpl.java中使用编程式事务管理:
package com.cy.service.impl; import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate; import com.cy.dao.BankDao;
import com.cy.service.BankService; public class BankServiceImpl implements BankService { private BankDao bankDao; private TransactionTemplate transactionTemplate; public void setTransactionTemplate(TransactionTemplate transactionTemplate) {
this.transactionTemplate = transactionTemplate;
} public void setBankDao(BankDao bankDao) {
this.bankDao = bankDao;
} //A向B转账count元
@Override
public void transferAccounts(final int count, final int userIdA, final int userIdB) {
transactionTemplate.execute(new TransactionCallbackWithoutResult(){ @Override
protected void doInTransactionWithoutResult(TransactionStatus arg0) {
bankDao.outMoney(count, userIdA);
bankDao.inMoney(count, userIdB);
}
});
} }
3)beans.xml中配置jdbc事务管理器、transactionTemplate:
<?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:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd"> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${jdbc.driverClassName}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean> <context:property-placeholder location="jdbc.properties"/> <!-- jdbc事务管理器 -->
<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> <bean id="namedParameterJdbcTemplate" class="org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate">
<constructor-arg ref="dataSource"></constructor-arg>
</bean> <bean id="bankDao" class="com.cy.dao.impl.BankDaoImpl">
<property name="namedParameterJdbcTemplate" ref="namedParameterJdbcTemplate"></property>
</bean> <bean id="bankService" class="com.cy.service.impl.BankServiceImpl">
<property name="bankDao" ref="bankDao"></property>
<property name="transactionTemplate" ref="transactionTemplate"></property>
</bean> </beans>
运行测试程序,报错,但是张三账户中仍然是500元,李四账户中没有收到钱,为500元。事务进行了回滚。
三、声明式事务管理:
1.使用xml配置声明式事务:
BankServiceImpl.java:
package com.cy.service.impl; import com.cy.dao.BankDao;
import com.cy.service.BankService; public class BankServiceImpl implements BankService { private BankDao bankDao; public void setBankDao(BankDao bankDao) {
this.bankDao = bankDao;
} //A向B转账count元
@Override
public void transferAccounts(final int count, final int userIdA, final int userIdB) {
bankDao.outMoney(count, userIdA);
bankDao.inMoney(count, userIdB);
} }
beans.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:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd"> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${jdbc.driverClassName}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean> <context:property-placeholder location="jdbc.properties"/> <!-- jdbc事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean> <!-- 配置事务通知 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="*"/>
</tx:attributes>
</tx:advice> <!-- 配置事务切面 -->
<aop:config>
<!-- 配置切点 -->
<aop:pointcut id="serviceMethod" expression="execution(* com.cy.service.*.*(..))" />
<!-- 配置事务通知 -->
<aop:advisor advice-ref="txAdvice" pointcut-ref="serviceMethod"/>
</aop:config> <bean id="namedParameterJdbcTemplate" class="org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate">
<constructor-arg ref="dataSource"></constructor-arg>
</bean> <bean id="bankDao" class="com.cy.dao.impl.BankDaoImpl">
<property name="namedParameterJdbcTemplate" ref="namedParameterJdbcTemplate"></property>
</bean> <bean id="bankService" class="com.cy.service.impl.BankServiceImpl">
<property name="bankDao" ref="bankDao"></property>
</bean> </beans>
运行测试代码,事务得到回滚。
2.使用注解配置声明式事务:
BankServiceImpl.java:
package com.cy.service.impl; import org.springframework.transaction.annotation.Transactional; import com.cy.dao.BankDao;
import com.cy.service.BankService; @Transactional
public class BankServiceImpl implements BankService { private BankDao bankDao; public void setBankDao(BankDao bankDao) {
this.bankDao = bankDao;
} //A向B转账count元
@Override
public void transferAccounts(final int count, final int userIdA, final int userIdB) {
bankDao.outMoney(count, userIdA);
bankDao.inMoney(count, userIdB);
} }
beans.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:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd"> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${jdbc.driverClassName}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean> <context:property-placeholder location="jdbc.properties"/> <!-- jdbc事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean> <tx:annotation-driven transaction-manager="transactionManager"/> <bean id="namedParameterJdbcTemplate" class="org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate">
<constructor-arg ref="dataSource"></constructor-arg>
</bean> <bean id="bankDao" class="com.cy.dao.impl.BankDaoImpl">
<property name="namedParameterJdbcTemplate" ref="namedParameterJdbcTemplate"></property>
</bean> <bean id="bankService" class="com.cy.service.impl.BankServiceImpl">
<property name="bankDao" ref="bankDao"></property>
</bean> </beans>
四、事务的传播行为:
read-only:只读的;
例如将上面xml中的事务通知修改为配置如下:
beans.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:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd"> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${jdbc.driverClassName}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean> <context:property-placeholder location="jdbc.properties"/> <!-- jdbc事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean> <!-- 配置事务通知 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="insert*" propagation="REQUIRED" />
<tx:method name="update*" propagation="REQUIRED" />
<tx:method name="edit*" propagation="REQUIRED" />
<tx:method name="save*" propagation="REQUIRED" />
<tx:method name="add*" propagation="REQUIRED" />
<tx:method name="new*" propagation="REQUIRED" />
<tx:method name="set*" propagation="REQUIRED" />
<tx:method name="remove*" propagation="REQUIRED" />
<tx:method name="delete*" propagation="REQUIRED" />
<tx:method name="change*" propagation="REQUIRED" />
<tx:method name="get*" propagation="REQUIRED" read-only="true" />
<tx:method name="find*" propagation="REQUIRED" read-only="true" />
<tx:method name="load*" propagation="REQUIRED" read-only="true" />
<tx:method name="transferAccounts" propagation="REQUIRED" />
<tx:method name="*" propagation="REQUIRED" read-only="true" />
</tx:attributes>
</tx:advice> <!-- 配置事务切面 -->
<aop:config>
<!-- 配置切点 -->
<aop:pointcut id="serviceMethod" expression="execution(* com.cy.service.*.*(..))" />
<!-- 配置事务通知 -->
<aop:advisor advice-ref="txAdvice" pointcut-ref="serviceMethod"/>
</aop:config> <bean id="namedParameterJdbcTemplate" class="org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate">
<constructor-arg ref="dataSource"></constructor-arg>
</bean> <bean id="bankDao" class="com.cy.dao.impl.BankDaoImpl">
<property name="namedParameterJdbcTemplate" ref="namedParameterJdbcTemplate"></property>
</bean> <bean id="bankService" class="com.cy.service.impl.BankServiceImpl">
<property name="bankDao" ref="bankDao"></property>
</bean> </beans>
-----------------------------
峰Spring4学习(8)spring对事务的支持的更多相关文章
- 【spring源码学习】spring的事务管理的源码解析
[一]spring事务管理(1)spring的事务管理,是基于aop动态代理实现的.对目标对象生成代理对象,加入事务管理的核心拦截器==>org.springframework.transact ...
- Spring(九)Spring对事务的支持
一.对事务的支持 事务:是一组原子操作的工作单元,要么全部成功,要么全部失败 Spring管理事务方式: JDBC编程事务管理:--可以控制到代码中的行 可以清楚的控制事务的边界,事务控制粒度化细(编 ...
- 峰Spring4学习(4)spring自动装配
一.自动装配: Model类: People.java: package com.cy.entity; public class People { private int id; private St ...
- 峰Spring4学习(6)spring AOP的应用例子
一.AOP简介: 二.AOP实例: 三.使用的例子 需求:在student添加的前后,打印日志信息: 0)spring AOP需要引用的jar包: 1)StudentService.java接口: p ...
- 峰Spring4学习(7)spring对JDBC的支持
第一节: 工程结构: 1)student.java: package com.cy.model; public class Student { private int id; private Stri ...
- spring4 学习4 spring MVC+mybatis+Mysql
在前面搭建的基础上,引入新的jar包如下: aopalliance-1.0.jaraspectjweaver-1.8.8.jarmybatis-3.3.0.jarmybatis-spring-1.2. ...
- 峰Spring4学习(5)bean之间的关系和bean的作用范围
一.bean之间的关系: 1)继承: People.java实体类: package com.cy.entity; public class People { private int id; priv ...
- 峰Spring4学习(3)注入参数的几种类型
People.java model类: package com.cy.entity; import java.util.ArrayList; import java.util.HashMap; im ...
- 峰Spring4学习(2)依赖注入的几种方式
一.装配一个bean 二.依赖注入的几种方式 com.cy.entity People.java: package com.cy.entity; public class People { pri ...
随机推荐
- Maven编译的时候加载本地路径jar
大家都知道Maven的依赖是通过pom文件管理的,只要配置了<dependency>,Maven就会从本地仓库 -> 远程仓库 -> 中央仓库获取依赖的jar. 但是如果仓库中 ...
- 【eclipse】运行maven项目clean tomcat7:run报错
问题: Failed to execute goal org.apache.maven.plugins:maven-clean-plugin:2.5:clean 解决: 关闭进程javaw.exe,然 ...
- [转] VR-FORCES 介绍
转自:https://sanwen8.cn/p/1e6GQeK.html 今天给各位介绍的仿真平台是VR-Forces.VR-Forces是新加坡公司MAK的产品,前身是美国公司.在仿真平台领域里面, ...
- JavaScript权威指南--window对象
知识要点 window对象及其客户端javascript所扮演的核心角色:它是客户端javascript程序的全局对象.本章介绍window对象的属性和方法,这些属性定义了不同的API,但是只有一部分 ...
- JAVA异常处理分析高级进界(下)
既然Throwable是异常处理机制的核心,那么,我们就来分析下它的源码来看看它是如何实现的. 进行分析前,我们可以先想想如果让我们实现一个异常处理机制,我们需要它做什么? 1. 发生异常终止程序执行 ...
- c# winform 操作oracle数据库的Blob字段,把图片存储到数据库,保存图片到数据库
///c# winform 操作oracle数据库的Blob字段,把图片存储到数据库,保存图片到数据库 闲话不多说,直接上代码 using System; using System.Collectio ...
- 转载-LVS的三种工作模式
来源地址:http://www.uml.org.cn/zjjs/201211124.asp 1.lvs简介 lvs是一个开源的软件,由毕业于国防科技大学的章文嵩博士于1998年5月创立 ...
- L202
Yuan Cao’s teenage years were hardly typical. By age 18, he had already graduated from high school, ...
- L177 Arctic ice brings an understanding of ancient Europe’s economy
Greenland's icy mountains are not an obvious place to search for an archive of economic history, but ...
- [Tomcat无法启动]'Starting Tomcat v8.0 Server at localhost' has encountered a problem.
运行一个index.jsp,运行提示如下错误:点击服务器 解决办法1: 点击Tomcat服务器,将服务器里的web工程删除掉,再重新运行index.jsp. 解决办法2: 关闭Tomcat,最简单的方 ...