spring学习笔记(7)——spring事务管理方式
来源:互联网 发布:德卡斯特里奥算法 编辑:程序博客网 时间:2024/06/05 05:19
spring事务管理有两种方式:一种是传统的编程式事务管理,即通过编写代码实现事务的管理,包括定义事务的开始、程序正常执行后事务提交、异常时进行事务回滚。
另一种是基于AOP技术实现的声明式事务,其主要思想是将事务管理作为一个“方面”代码单独编写,程序员只关心核心业务逻辑代码,然后通过AOP技术将事务管理的“方面”代码织入到业务类中。
下面通过一个银行转账的例子说明事务:
首先先配置好ssh框架见spring笔记(6)。
- 数据库实体类和映射文件
实体类:
package com.test.bean;public class Account { private int id; private String accountNo; private double balance; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getAccountNo() { return accountNo; } public void setAccountNo(String accountNo) { this.accountNo = accountNo; } public double getBalance() { return balance; } public void setBalance(double balance) { this.balance = balance; }}
2、DAO层
package com.test.dao;import java.util.List;import com.test.bean.Account;public interface AccountDAO { // 根据账号获取账户对象 public List getAccountByAccountNo(String accountNo); // 转账 public void transfer(Account a1, Account a2);}
package com.test.dao.impl;import java.util.List;import org.springframework.orm.hibernate3.support.HibernateDaoSupport;import com.test.bean.Account;import com.test.dao.AccountDAO;public class AccountDAOImpl extends HibernateDaoSupport implements AccountDAO { //转账 public void transfer(Account a1, Account a2) { this.getHibernateTemplate().update(a1); this.getHibernateTemplate().update(a2); } //根据账号获取账户对象 public List getAccountByAccountNo(final String accountNo) { // TODO Auto-generated method stub String hql ="from Account account where account.accountNo=?"; return this.getHibernateTemplate().find(hql,accountNo); }}
3、service层
package com.test.service;import java.util.List;import com.test.bean.Account;public interface AccountService { // 根据账号获取账户对象 public List getAccountByAccountNo(String accountNo); // 转账 public void transfer(Account a1, Account a2);}
package com.test.service.impl;import java.util.List;import com.test.bean.Account;import com.test.dao.AccountDAO;import com.test.service.AccountService;public class AccountServiceImpl implements AccountService{ //用AccountDAO接口声明对象,并添加set方法用于依赖注入 AccountDAO accountDAO; public void setAccountDAO(AccountDAO accountDAO) { this.accountDAO = accountDAO; } //转账 //使用@Transactional注解实现transfer方法的事务管理 public void transfer(Account a1, Account a2) { accountDAO.transfer(a1, a2); } //根据账号获取账户对象 public List getAccountByAccountNo(String accountNo) { // TODO Auto-generated method stub return accountDAO.getAccountByAccountNo(accountNo); }}
4、action层
package com.test.action.account;import java.util.List;import com.opensymphony.xwork2.ActionSupport;import com.test.bean.Account;import com.test.service.AccountService;public class AccountManagerAction extends ActionSupport { // 定义属性,用于封装表单数据 private String ac1; private String ac2; private String amount; public String getAc1() { return ac1; } public void setAc1(String ac1) { this.ac1 = ac1; } public String getAc2() { return ac2; } public void setAc2(String ac2) { this.ac2 = ac2; } public String getAmount() { return amount; } public void setAmount(String amount) { this.amount = amount; } // 使用AccountBiz接口声明对象,并添加set方法用于依赖注入 private AccountService service; public void setAccountService(AccountService service) { this.service = service; } @Override // 执行请求 public String execute() throws Exception { System.out.println(ac1); System.out.println(ac2); Account a1 = null; Account a2 = null; // 获取账号ac1的账户对象,并更新对象中的账户余额属性 List list1 = service.getAccountByAccountNo(ac1); if (list1.size() > 0) { a1 = (Account) list1.get(0); System.out.println("ac1"); a1.setBalance((a1.getBalance() - Double.parseDouble(amount))); } // 获取账号ac2的账户对象,并更新对象中的账户余额属性 List list2 = service.getAccountByAccountNo(ac2); if (list2.size() > 0) { a2 = (Account) list2.get(0); System.out.println("ac2"); a2.setBalance((a2.getBalance() + Double.parseDouble(amount))); } try { // 执行转账操作 service.transfer(a1, a2); System.out.println("transfer"); } catch (Exception e) { // 转账失败 System.out.println(e); return "error1"; } // 转账成功 return "success1"; }}
5、spring配置文件applicationContext.xml中配置相关类
<!-- 定义AccountDAOImpl类实例,并将已经创建LocalSessionFactoryBean的实例 sessionFactory依赖注入到UserDAOImpl类所继承的 HibernateDaoSupport 的sessionFactory属性 --> <bean id="accountDAO" class="com.test.dao.impl.AccountDAOImpl"> <property name="sessionFactory" ref="sessionFactory" /> </bean> <bean id="accountService" class="com.test.service.impl.AccountServiceImpl"> <property name="accountDAO" ref="accountDAO" /> </bean> <!-- 部署Struts 2的负责账户管理的控制器AccountManager --> <bean id="amAction" class="com.test.action.account.AccountManagerAction"> <property name="accountService" ref="accountService" /> </bean>
6、struts.xml配置
<action name="doTransfer" class="amAction"> <!-- 定义处理结果和资源之间的映射关系 --> <result name="error1">error1.jsp</result> <result name="success1">success1.jsp</result></action>
7、配置声明事务
(1)、在spring配置文件中增加事务管理所需的常用命名空间声明
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
(2)、声明事务管理器,在声明事务管理器时需要注入sessionFactory属性。定义事务通知,定义事务通知时需要指定一个事务管理器,然后在其属性中声明事务规则。
<!-- 声明事务管理器 --> <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> <property name="sessionFactory"> <ref bean="sessionFactory" /> </property> </bean> <!-- 定义事务通知 --> <tx:advice id="txAdvice" transaction-manager="transactionManager"> <!-- 指定事务传播规则 --> <tx:attributes> <!-- 对get打头的方法应用SUPPORTS事务规则 --> <tx:method name="get*" propagation="SUPPORTS" /> <!-- 对其他方法应用REQUIRED事务规则 --> <tx:method name="*" propagation="REQUIRED"></tx:method> </tx:attributes> </tx:advice> <!-- 定义切面,并将事务通知和切面组合(定义哪些方法应用事务规则) --> <aop:config> <aop:pointcut id="serviceMethods" expression="execution(* com.test.service.*.*(..))" /> <!-- 将事务通知和切面组合 --> <aop:advisor advice-ref="txAdvice" pointcut-ref="serviceMethods" /> </aop:config>
8、编写测试页面
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%><%@ taglib prefix="s" uri="/struts-tags"%> <html> <head> <title>转账页面</title> </head> <body> <s:form action="doTransfer.action"> <s:textfield name="ac1" label="账户1" /> <s:textfield name="ac2" label="账户2" /> <s:textfield name="amount" label="转账金额" /> <s:submit value="转账" /> </s:form> </body></html>
第一次测试:
数据库:
第二次测试:
数据库:
账户输入错误,两个账户余额均不变化。
第三次测试:
将spring配置文件中一下代码删去,及删除声明式事务。重启工程后。
在执行第二次的操作:
0 0
- spring学习笔记(7)——spring事务管理方式
- spring学习(十)—事务管理(配置文件方式实现)
- spring学习(十一)—事务管理(注解方式实现)
- spring学习笔记8——事务管理
- 【Spring学习笔记】Spring事务管理(一)
- spring学习笔记(4)-spring事务管理
- Spring事务管理学习笔记
- Spring学习笔记----事务管理
- Spring事务管理学习笔记
- Spring学习笔记 事务管理
- Spring学习笔记---7-Spring事务管理(3)
- spring学习笔记:spring事务管理
- spring学习笔记:spring事务管理
- spring学习笔记:spring事务管理
- Beginning Spring学习笔记——第6章(一)Spring事务管理基础
- JAVAWEB开发之Spring详解之——Spring事务管理详解(四种事务管理方式)
- Spring学习笔记(八)事务管理
- Spring.NET学习笔记16——事务管理(应用篇)
- Unity ----- 对象池GameObjectPool
- java初学者知识小总结-01(byte数据类型赋值出错)
- unity的自动寻路之 ------ wayPoint寻路的实现方式
- unix环境高级编程----进程控制wait()
- Storm开发过程中遇到的Topology “hang"问题
- spring学习笔记(7)——spring事务管理方式
- 启动oracle服务和监听的批处理
- 1.hibernate入门
- Html5无刷新修改Url,history pushState/replaceState
- C/C++中static关键字详解
- easeljs中text控件示例
- 深入探讨 java.lang.ref 包
- Android下资源使用的方式-android学习之旅(五十三)
- cocos2d-x3.6 连连看触摸事件传递