spring 手动递交事务 spring提交事务
转载
事务处理在应用程序中起着至关重要的作用。本篇博客将进入Spring的事务处理学习。下面,首先我们来简单回想一下与事务有关的一些概念。
【事务】
所谓事务,就是一系列必须成功的操作,只要有一步操作失败,所以其他步骤都将要撤销。当所有的步骤都执行完成后,则该事务提交成功。由于操作中的某一个步骤失败,导致所有的步骤都没有提交,则事务必须回滚,即回到事务前的状态。
【Spring事务概述】
Spring的事务处理分为编程式事务和声明式事务。它们的实现都是基于AOP机制。通过前面的学习,我们也了解到Spring会默认使用Java的动态代理机制,因为Java的动态代理机制要求其代理的对象必须实现一个接口,并且在该接口中定义准备进行代理的方法。而对于没有实现任何接口的对象,则Spring使用CGLIB实现。
【编程式事务】
下面以添加用户的时候,记录一条日志为实例,通过编程的方式,添加事务。
用户实体:
package com.bjpowernode.usermgr.domain;
public class User {
private int id;
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
package com.bjpowernode.usermgr.domain;
import java.util.Date;
public class Log {
private int id;
//日志类别,日志一般起到一个不可否认性
//操作日志、安全日志、事件日志
private String type;
private String detail;
private Date time;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getDetail() {
return detail;
}
public void setDetail(String detail) {
this.detail = detail;
}
public Date getTime() {
return time;
}
public void setTime(Date time) {
this.time = time;
}
}
package com.bjpowernode.usermgr.util;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
public class HibernateUtils {
private static SessionFactory factory;
private HibernateUtils() {
}
static {
try {
Configuration cfg = new Configuration().configure();
factory = cfg.buildSessionFactory();
}catch(Exception e) {
e.printStackTrace();
throw new java.lang.RuntimeException(e);
}
}
public static SessionFactory getSessionFactory() {
return factory;
}
public static Session getSession() {
return factory.openSession();
}
public static void closeSession(Session session) {
if (session != null) {
if (session.isOpen()) {
session.close();
}
}
}
}
用户管理,编写事务,添加用户的同时添加一条日志信息:
package com.bjpowernode.usermgr.manager;
import java.util.Date;
import org.hibernate.Session;
import com.bjpowernode.usermgr.domain.Log;
import com.bjpowernode.usermgr.domain.User;
import com.bjpowernode.usermgr.util.HibernateUtils;
public class UserManagerImpl implements UserManager {
public void addUser(User user) {
Session session = null;
try {
//session = HibernateUtils.getSession();
//取得session
session = HibernateUtils.getSessionFactory().getCurrentSession();
session.beginTransaction(); //开启事务
//保存用户
session.save(user);
//设置日志
Log log = new Log();
log.setType("操作日志");
log.setTime(new Date());
log.setDetail("XXX");
LogManager logManager = new LogManagerImpl();
//保存日志
logManager.addLog(log);
Integer.parseInt("adfsadfdsf");
session.getTransaction().commit(); //提交事务
}catch(Exception e) {
e.printStackTrace();
session.getTransaction().rollback(); //回滚事务
//}finally {
// HibernateUtils.closeSession(session);
}
}
}
OpenSession与GetCurrentSession的区别?
* openSession必须关闭,currentSession在事务结束后自动关闭
* openSession没有和当前线程绑定,currentSession和当前线程绑定
如果使用currentSession需要在hibernate.cfg.xml文件中进行配置:
* 如果是本地事务(jdbc事务)
<property name="hibernate.current_session_context_class">thread</property>
* 如果是全局事务(jta事务)
<property name="hibernate.current_session_context_class">jta</property>
【声明式事务】
在系统中,事务的配置只需要在一个地方即可,所以,可以将事务配置到单独的ApplicationContext配置文件中,如下:
<?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:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">
<!-- 配置SessionFactory -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="configLocation">
<value>classpath:hibernate.cfg.xml</value>
</property>
</bean>
<!-- 配置事务管理器 -->
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory">
<ref bean="sessionFactory"/>
</property>
</bean>
<!-- 哪些类哪些方法使用事务 -->
<aop:config>
<aop:pointcut id="allManagerMethod" expression="execution(* com.bjpowernode.usermgr.manager.*.*(..))"/>
<aop:advisor pointcut-ref="allManagerMethod" advice-ref="txAdvice"/>
</aop:config>
<!-- 事务的传播特性 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="add*" propagation="REQUIRED"/>
<tx:method name="del*" propagation="REQUIRED"/>
<tx:method name="modify*" propagation="REQUIRED"/>
<tx:method name="*" propagation="REQUIRED" read-only="true"/>
</tx:attributes>
</tx:advice>
</beans>
用户管理代码,不需要在写事务的开启、提交及回滚的代码,继承spring提供的HibernateDaoSupport:
package com.bjpowernode.usermgr.manager;
import java.util.Date;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import com.bjpowernode.usermgr.domain.Log;
import com.bjpowernode.usermgr.domain.User;
public class UserManagerImpl extends HibernateDaoSupport implements UserManager {
private LogManager logManager;
public void addUser(User user) throws Exception {
//this.getSession().save(user);
this.getHibernateTemplate().save(user);
Log log = new Log();
log.setType("操作日志");
log.setTime(new Date());
log.setDetail("XXX");
logManager.addLog(log);
throw new Exception();
}
public void setLogManager(LogManager logManager) {
this.logManager = logManager;
}
}
在Spring配置文件中,将logmanager和usermanager注入,并将logmanager注入到usermanager中:
<?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:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">
<bean id="userManager" class="com.bjpowernode.usermgr.manager.UserManagerImpl">
<property name="sessionFactory" ref="sessionFactory"/>
<property name="logManager" ref="logManager"/>
</bean>
<bean id="logManager" class="com.bjpowernode.usermgr.manager.LogManagerImpl">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
</beans>
【总结】
本篇博客介绍了Spring中的事务处理,其中,编程式事务主要是用Hibernate实现的,我们需要在程序中编写事务的开启、提交及回滚的相关代码;而声明式事务是使用Spring与Hibernate集成实现的,使用此方法,我们可以将系统中的事务配置为一个单独的配置文件,对象通过继承HibernateDaoSupport,可以取得Session,从而在Spring配置文件中,将对象间的关系配置即可,相对来说,更加灵活方便。
本文章为转载内容,我们尊重原作者对文章享有的著作权。如有内容错误或侵权问题,欢迎原作者联系我们进行内容更正或删除文章。