环境与版本

除了上一篇中的hibernate的相关lib 外

Java事务管理之Hibernate

还需要加入Spring的lib 包和如下的一些依赖包

org.aopalliance
org.aspectj
org.apache.commons

Spring 的版本是Spring 4.1.5。

依赖包也可以到Spring 官方网站下载到 ,名字类似 spring-framework-3.0.2.RELEASE-dependencies

理论知识

Spring和Hibernate整合后,通过Hibernate API进行数据库操作时发现每次都要opensession,close,beginTransaction,commit,这些都是重复的工作,我们可以把事务管理部分交给spring框架完成。

使用spring管理事务后在dao中不再需要调用beginTransaction和commit,也不需要调用session.close(),使用API  sessionFactory.getCurrentSession()来替代sessionFactory.openSession()

* 如果使用的是本地事务(jdbc事务)
<property name="hibernate.current_session_context_class">thread</property>
* 如果使用的是全局事务(jta事务)
<property name="hibernate.current_session_context_class">jta</property>

Spring中Propagation类的事务属性详解:
PROPAGATION_REQUIRED:支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。 
PROPAGATION_SUPPORTS:支持当前事务,如果当前没有事务,就以非事务方式执行。 
PROPAGATION_MANDATORY:支持当前事务,如果当前没有事务,就抛出异常。 
PROPAGATION_REQUIRES_NEW:新建事务,如果当前存在事务,把当前事务挂起。
PROPAGATION_NOT_SUPPORTED:以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。 
PROPAGATION_NEVER:以非事务方式执行,如果当前存在事务,则抛出异常。 
PROPAGATION_NESTED:支持当前事务,如果当前事务存在,则执行一个嵌套事务,如果当前没有事务,就新建一个事务。

Spring 可以使用xml方式进行配置或是使用注解声明的方式进行事务的管理。

xml 方式配置事务代码实例

代码结构如下:

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:p="http://www.springframework.org/schema/p"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:util="http://www.springframework.org/schema/util" xmlns:mvc="http://www.springframework.org/schema/mvc"
	xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xsi:schemaLocation="
        http://www.springframework.org/schema/util
        http://www.springframework.org/schema/util/spring-util-3.1.xsd
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-3.1.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc-3.1.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">

	<context:component-scan base-package="com.oscar999.trans.sprhib" />
	<context:property-placeholder location="classpath:/com/oscar999/trans/sprhib/config.properties" />
	<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
		destroy-method="close">
		<!-- Connection Info -->
		<property name="driverClassName" value="${jdbc.driver}" />
		<property name="url" value="${jdbc.url}" />
		<property name="username" value="${jdbc.username}" />
		<property name="password" value="${jdbc.password}"></property>
	</bean>

	<bean id="sessionFactory"
		class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
		<property name="dataSource" ref="dataSource"></property>
		<property name="hibernateProperties">
			<props>
				<prop key="hibernate.dialect">org.hibernate.dialect.OracleDialect</prop>
				<prop key="hibernate.hbm2ddl.auto">update</prop>
				<prop key="hibernate.show_sql">true</prop>
				<prop key="hibernate.format_sql">true</prop>
				<prop key="hibernate.jdbc.batch_size">20</prop>
				<prop key="hibernate.enable_lazy_load_no_trans">true</prop>
				<prop key="hibernate.current_session_context_class">org.springframework.orm.hibernate4.SpringSessionContext</prop>
				<prop key="jdbc.use_streams_for_binary">true</prop>
			</props>
		</property>
		<property name="packagesToScan">
			<list>
				<value>com.oscar999.trans.sprhib.model</value>
			</list>
		</property>
	</bean>

	<!-- Transaction -->
	<bean id="transactionManager"
		class="org.springframework.orm.hibernate4.HibernateTransactionManager">
		<property name="sessionFactory" ref="sessionFactory" />
	</bean>
	<tx:advice id="txAdvice" transaction-manager="transactionManager">
		<tx:attributes>
			<tx:method name="save*" propagation="REQUIRED" />
			<tx:method name="*" read-only="true" />
		</tx:attributes>
	</tx:advice>
	<aop:config proxy-target-class="true">
		<aop:pointcut expression="execution(* com.oscar999.trans.sprhib.dao.ProductDAOImpl.*(..))" id="pointcut" />
		<aop:advisor advice-ref="txAdvice" pointcut-ref="pointcut" />
	</aop:config>

</beans>

config.properties

jdbc.driver=oracle.jdbc.driver.OracleDriver
jdbc.url=jdbc:oracle:thin:@12.6.18.43:1521:orcl
jdbc.username=
jdbc.password=oracle

Product.java

/**
 * @Title: Product.java
 * @Package com.oscar999.trans.hibernate
 * @Description:
 * @author XM
 * @date Feb 15, 2017 1:44:47 PM
 * @version V1.0
 */
package com.oscar999.trans.sprhib.model;

import java.io.Serializable;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;

/**
 * @author XM
 *
 */
@Entity
@Table(name = "TEST_PRODUCT")
public class Product implements Serializable {

	public Product() {
	}

	@Id
	@Column(name = "ID")
	private Integer id;

	@Column(name = "NAME")
	private String name;

	@Column(name = "PRICE")
	private String price;

	private static final long serialVersionUID = 1L;

	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getPrice() {
		return price;
	}

	public void setPrice(String price) {
		this.price = price;
	}

}

ProductDAOImpl.java

/**
 * @Title: ProductDAOImpl.java
 * @Package com.oscar999.trans.sprhib
 * @Description:
 * @author XM
 * @date Feb 15, 2017 4:15:09 PM
 * @version V1.0
 */
package com.oscar999.trans.sprhib.dao;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import com.oscar999.trans.sprhib.model.Product;

/**
 * @author XM
 *
 */
@Repository
public class ProductDAOImpl {

	@Autowired
	private SessionFactory sessionFactory; 

	public Product findProductById(int id) {
		Session session = sessionFactory.getCurrentSession();
		Product product = (Product) session.get(Product.class, id);
		return product;
	}

	public Product saveProduct(Product product) {
		Session session = sessionFactory.getCurrentSession();
		session.save(product);
		return product;
	}
}

ProductServiceImpl.java

package com.oscar999.trans.sprhib;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.oscar999.trans.sprhib.dao.ProductDAOImpl;
import com.oscar999.trans.sprhib.model.Product;

@Service
public class ProductServiceImpl {

	@Autowired
	private ProductDAOImpl productdao;

	public void findProduct(int id) {
		Product product = productdao.findProductById(id);
		if (product != null) {
			System.out.println(product.getName());
		}
	}

	public void saveProduct() {
		Product product = new Product();
		product.setId(2);
		product.setName("product2");
		product.setPrice("price2");
		productdao.saveProduct(product);

	}
}

TestMain.java

/**
 * @Title: TestMain.java
 * @Package com.oscar999.trans.sprhib
 * @Description:
 * @author XM
 * @date Feb 15, 2017 3:54:54 PM
 * @version V1.0
 */
package com.oscar999.trans.sprhib;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * @author XM
 *
 */
public class TestMain {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext("com/oscar999/trans/sprhib/applicationContext.xml");
		ProductServiceImpl productService = applicationContext.getBean(ProductServiceImpl.class);
		//productService.findProduct(1);
		productService.saveProduct();
	}

}

说明如下:

get 可以不需要transaction
插入或是更新如果没有的话, 就不会更新成功

声明方式配置事务

需要在xml配制中设置<tx:annotation-driven transaction-manager="transactionManager"> 
事物注解方式: @Transactional
当标于类前时,标示类中所有方法都进行事物处理,以下代码在service层进行事务处理(给Service层配置事务是比较好的方式,因为一个Service层方法操作可以关联到多个DAO的操作。在Service层执行这些Dao操作,多DAO操作有失败全部回滚,成功则全部提交。)

@Service

@Transactional

public class UserServiceImpl implements UserService {

@Autowired

private UserDao userDao;

public User getUserById(int id) {

return userDao.findUserById(id);

}

}

当类中某些方法不需要事物时:
@Service

@Transactional

public class UserServiceImpl implements UserService {

@Autowired

private UserDao userDao;

@Transactional(propagation = Propagation.NOT_SUPPORTED)

public User getUserById(int id) {

return userDao.findUserById(id);

}

}

Java事务管理之Spring+Hibernate的更多相关文章

  1. 程序员笔记|Spring IoC、面向切面编程、事务管理等Spring基本概念详解

    一.Spring IoC 1.1 重要概念 1)控制反转(Inversion of control) 控制反转是一种通过描述(在java中通过xml或者注解)并通过第三方去产生或获取特定对象的方式. ...

  2. 带事务管理的spring数据库动态切换

    动态切换数据源理论知识 项目中我们经常会遇到多数据源的问题,尤其是数据同步或定时任务等项目更是如此:又例如:读写分离数据库配置的系统. 1.相信很多人都知道JDK代理,分静态代理和动态代理两种,同样的 ...

  3. Java事务管理之Hibernate

    环境与版本 Hibernate 版本:Hibernate 4.2.2 (下载后的文件名为hibernate-release-4.2.2.Final.zip,解压目录hibernate-release- ...

  4. 框架源码系列十一:事务管理(Spring事务管理的特点、事务概念学习、Spring事务使用学习、Spring事务管理API学习、Spring事务源码学习)

    一.Spring事务管理的特点 Spring框架为事务管理提供一套统一的抽象,带来的好处有:1. 跨不同事务API的统一的编程模型,无论你使用的是jdbc.jta.jpa.hibernate.2. 支 ...

  5. atomikos实现多数据源支持分布式事务管理(spring、tomcat、JTA)

    原文链接:http://iteye.blog.163.com/blog/static/1863080962012102945116222/   Atomikos TransactionsEssenti ...

  6. java事务管理

    一.什么是Java事务 通常的观念认为,事务仅与数据库相关. 事务必须服从ISO/IEC所制定的ACID原则.ACID是原子性(atomicity).一致性(consistency).隔离性(isol ...

  7. spring事务管理-Spring 源码系列(6)

    Spring事务抽象的是事务管理和事务策略.而实现则由各种资源方实现的.我们最常用的数据库实现:DataSourceTransactionManager 尝试阅读一下spring 的实现代码,由3个核 ...

  8. spring测试junit事务管理及spring面向接口注入和实现类单独注入(无实现接口),实现类实现接口而实现类单独注入否则会报错。

    1.根据日志分析,spring junit默认是自动回滚,不对数据库做任何的操作. 18:16:57.648 [main] DEBUG o.s.j.d.DataSourceTransactionMan ...

  9. Java事务管理之JDBC

    前言 关于Java中JDBC的一些使用可以参见: Java 中使用JDBC连接数据库例程与注意事项 在使用JDBC的使用, 如何进行事务的管理.直接看一下代码 示例代码 /** * @Title: J ...

随机推荐

  1. fzyzojP2119 -- 圆圈游戏

    说白了,就是这个样子: 这个玩意明显是一个优美的树形结构 是个森林 然后建个虚点0,并且w[0]=0,然后树形dp即可 f[x]=max(w[x],∑f[son]) 难点是:树怎么建? 就要上计算几何 ...

  2. [转]Multivariate Time Series Forecasting with LSTMs in Keras

    1. Air Pollution Forecasting In this tutorial, we are going to use the Air Quality dataset. This is ...

  3. spoj 375 树链剖分 模板

    QTREE - Query on a tree #tree You are given a tree (an acyclic undirected connected graph) with N no ...

  4. Android Studio 安装在Windows10中的陷阱

    操作系统:Windows 10 Pro CPU:AMD IDE:Android Studio 2.0 JDK:8.0 安装完AS(Android Studio)之后,运行AS发现无法启动模拟器,提示“ ...

  5. 科学计算三维可视化---TVTK管线与数据加载(数据集)

    一:数据集 三维可视化的第一步是选用合适的数据结构来表示数据,TVTK提供了多种表示不同种类数据的数据集 (一)数据集--ImageData >>> from tvtk.api im ...

  6. Java并发编程原理与实战四十五:问题定位总结

    背景   “线下没问题的”. “代码不可能有问题 是系统原因”.“能在线上远程debug么”    线上问题不同于开发期间的bug,与运行时环境.压力.并发情况.具体的业务相关.对于线上的问题利用线上 ...

  7. php设计模式之工厂设计模式

    概念:        工厂设计模式提供获取某个对象的新实例的一个接口,同时使调用代码避免确定实际实例化基类步骤. 很多高级模式都是依赖于工厂模式. 好处:         PHP中能够创建基于变量内容 ...

  8. centos7 源码构建、安装dubbo-monitor

    按照官方文档 ,发现dubbo-monitor-simple-x.x.x-assembly.tar.gz  下载不下来(地址访问不了),那么就自己下载源码构建吧. 我的zookeeper,hadoop ...

  9. 20155336 2016-2017-2《JAVA程序设计》第七周学习总结

    20155336 2016-2017-2<JAVA程序设计>第七周学习总结 教材学习内容总结 第十三章 认识时间与日期 格林威治标准时间:简称GMT时间,参考格林威治皇家天文台的标准太阳时 ...

  10. HDU 1717 小数化分数2 数学题

    解题报告:输入一个小于1的小数,让你把这个数转化成分数,但注意,输入的数据还有无限循环的小数,循环节用一对括号包含起来. 之前还没有写过小数转分数的题,当然如果没有循环小数的话,应该比较简单,但是这题 ...