Java事务管理之Hibernate
环境与版本
Hibernate 版本:Hibernate 4.2.2 (下载后的文件名为hibernate-release-4.2.2.Final.zip,解压目录hibernate-release-4.2.2.Final)
数据库: oracle 10g
导入lib\required 中的所有jar 包
理论说明
1.SessionFactory负责创建Session,SessionFactory是线程安全的,多个并发线程可以同时访问一个SessionFactory 并从中获取Session实例
2.Session作为贯穿Hibernate的持久化管理器核心,提供了众多的持久化的方法,如save(), update ,delete ,find(Hibernate 3中已经取消了此方法)等,通过这些方法我们可以透明的完成对象的增删改查(CRUD-- create read update delete),这里所谓的透明是指,Session在读取,创建和删除影射的实体对象的实例时,这一系列的操作将被转换为对数据库表中数据的增加,修改,查询和删除操作。
Session有以下的特点
  1)不是线程安全的,应该避免多个线程共享同一个Session实例 
  2)Session实例是轻量级的,所谓轻量级:是指他的创建和删除不需要消耗太多资源 
  3)Session对象内部有一个缓存,被称为Hibernate第一缓存,他存放被当前工作单元中加载的对象,每个Session实例都有自己的缓存。
3.Hibernate Session缓存被称为Hibernate的第一级缓存。SessionFactory的外置缓存称为Hibernate的二级缓存。这两个缓存都位于持久层,它们存放的都是数据库数据的拷贝。SessionFactory的内置缓存 存放元数据和预定义SQL, SessionFactory的内置缓存是只读缓存。
4. Hibernate Session缓存的三大作用:
1)减少数据库的访问频率,提高访问性能。
2)保证缓存中的对象与数据库同步,位于缓存中的对象称为持久化对象。
3)当持久化对象之间存在关联时,Session 保证不出现对象图的死锁。
Session 如何判断持久化对象的状态的改变呢?
Session 加载对象后会为对象值类型的属性复制一份快照。当Session 清理缓存时,比较当前对象和它的快照就可以知道那些属性发生了变化。
5. Session 什么时候清理缓存?
1)commit() 方法被调用时
2)查询时会清理缓存,保证查询结果能反映对象的最新状态。
3)显示的调用session 的 flush方法。
session 清理缓存的特例:
当对象使用 native 生成器 时 会立刻清理缓存向数据库中插入记录。
实例代码
测试的代码目录如下:
hibernate.cfg.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>
        <property name="show_sql">true</property>
        <property name="hibernate.connection.driver_class">
            oracle.jdbc.driver.OracleDriver
        </property>
        <property name="hibernate.connection.url">
            jdbc:oracle:thin:@XX.26.158.43:1521:orcl
        </property>
        <property name="hibernate.connection.username"></property>
        <property name="hibernate.connection.password"></property>
        <property name="dialect">org.hibernate.dialect.OracleDialect</property>  
        <mapping resource="com/oscar999/trans/hibernate/Product.hbm.xml"/>
    </session-factory>
</hibernate-configuration>
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.hibernate;
import java.io.Serializable;
/**
 * @author XM
 *
 */
public class Product implements Serializable {
	public Product() {
	}
	private Integer id;
	private String name;
	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;
	}
}
Product.hbm.xml
<?xml version="1.0"?> <!DOCTYPE hibernate-mapping SYSTEM "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd" > <hibernate-mapping> <class name="com.oscar999.trans.hibernate.Product" table="TEST_PRODUCT"> <id name="id" column="id" type="java.lang.Integer"> <generator class="assigned" /> </id> <property name="name" column="name" type="java.lang.String" not-null="true" unique="true" length="20" /> <property name="price" column="price" type="java.lang.String" not-null="false" unique="false" length="20" /> </class> </hibernate-mapping>
TestMain.java
/**
 * @Title: TestMain.java
 * @Package com.oscar999.trans.hibernate
 * @Description:
 * @author XM
 * @date Feb 15, 2017 2:02:17 PM
 * @version V1.0
 */
package com.oscar999.trans.hibernate;
import java.io.File;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.ServiceRegistryBuilder;
/**
 * @author XM
 *
 */
public class TestMain {
	/**
	 * @param args
	 */
	public Session getSession() {
		Session session = null;
		Configuration conf = new Configuration().configure(new File("src/com/oscar999/trans/hibernate/hibernate.cfg.xml"));
		ServiceRegistry serviceRegistry = new ServiceRegistryBuilder().applySettings(conf.getProperties()).buildServiceRegistry();
		SessionFactory sf = conf.buildSessionFactory(serviceRegistry);
		session = sf.openSession();
		return session;
	}
	public void addProduct(Session session, String name, String price) {
		Transaction t = session.beginTransaction(); // 1. comment1
		Product product = new Product();
		product.setId(1);
		product.setName(name);
		product.setPrice(price);
		try {
			session.save(product);
			t.commit(); // 2. comment2
		} catch (Exception e) {
			t.rollback();
		}
	}
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		TestMain testMain = new TestMain();
		Session session = testMain.getSession();
		testMain.addProduct(session, "product1", "price1");
		if (session != null && session.isOpen()) {
			session.close();
		}
	}
}
说明:
1. <generator class="assigned" /> 
id 的产生策略是自己指定, 所以在代码中有 product.setId(1); 否则无法添加成功
2.  Transaction t = session.beginTransaction();
Hibernate本身没有实现自己的事务管理功能,而是对底层JDBC事务或JTA事务的轻量级封装
3.
Hibernate可以配置为JDBCTransaction或者是JTATransaction,这取决于你在hibernate.properties中的配置: 
#hibernate.transaction.factory_class net.sf.hibernate.transaction.JTATransactionFactory 
#hibernate.transaction.factory_class net.sf.hibernate.transaction.JDBCTransactionFactory
如果你什么都不配置,默认情况下使用JDBCTransaction
4. 在Hibernate中,Session打开的时候,就会自动conn.setAutoCommit(false),不像一般的JDBC,默认都是true,所以你最后不写commit也没有关系,由于Hibernate已经把AutoCommit给关掉了,所以用Hibernate的时候,你在程序中不写Transaction的话,数据库根本就没有反应。
JDBC和Hibernate 处理事务的关联
Hibernate本身没有实现自己的事务管理功能,而是对底层JDBC事务或JTA事务的轻量级封装
JTA
javax.transaction.UserTransaction tx = new InitialContext();.lookup("javax.transaction.UserTransaction");;
Session s1 = sf.openSession();;
...
s1.flush();;
s1.close();;
...
Session s2 = sf.openSession();;
...
s2.flush();;
s2.close();;
tx.commit();;
Hibernate Transaction是从Session中获得的,tx = session.beginTransaction(),最后要先提交tx,然后再session.close,这完全符合JDBC的Transaction的操作顺序,但是这个顺序是和JTA的Transactioin操作顺序彻底矛盾的!!! JTA是先启动Transaction,然后启动Session,关闭Session,最后提交Transaction,因此当你使用JTA的Transaction的时候,那么就千万不要使用Hibernate的Transaction,而是应该像我上面的JTA的代码片断那样使用才行。
Java事务管理之Hibernate的更多相关文章
- Java事务管理之Spring+Hibernate
		环境与版本 除了上一篇中的hibernate的相关lib 外 Java事务管理之Hibernate 还需要加入Spring的lib 包和如下的一些依赖包 org.aopallianceorg.aspe ... 
- java事务管理
		一.什么是Java事务 通常的观念认为,事务仅与数据库相关. 事务必须服从ISO/IEC所制定的ACID原则.ACID是原子性(atomicity).一致性(consistency).隔离性(isol ... 
- Java事务管理之JDBC
		前言 关于Java中JDBC的一些使用可以参见: Java 中使用JDBC连接数据库例程与注意事项 在使用JDBC的使用, 如何进行事务的管理.直接看一下代码 示例代码 /** * @Title: J ... 
- java事务管理(二)
		数据库事务和Spring事务是一般面试都会被提到,很多朋友写惯了代码,很少花时间去整理归纳这些东西,结果本来会的东西,居然吞吞吐吐答不上来. 下面是我收集到一些关于Spring事务的问题,希望能帮助大 ... 
- Hibernate框架笔记02_主键生成策略_一级缓存_事务管理
		目录 0. 结构图 1. 持久化类的编写规则 1.1 持久化和持久化类 1.2 持久化类的编写规则 2. 主键生成策略 2.1 主键的分类 2.2 主键生成策略 3. 持久化类的三种状态[了解] 3. ... 
- Hibernate 事务管理
		一. 事务包含四个基本特性:简称ACID: 1. Atomic(原子性):全部成功或全部失败: 2. Consistency(一致性):只有合法数据才能被写入,不合法则回滚到最初状态: 3. Isol ... 
- JDBC、JTA、Spring的事务管理
		Java事务的类型有三种:JDBC事务.JTA(Java Transaction API)事务.容器事务. 事务就是对一系列的数据库操作(比如插入多条数据)进行统一的提交或回滚操作,如果插入成功,那么 ... 
- 【sping揭秘】22、事务管理
		有关事务的楔子 什么是事务??? 事务就是以可控的方式对数据资源进行访问的一组操作. 事务本身持有四个限定属性 原子性,一致性,隔离性,持久性 事务家族 Resource Manager RM,负责 ... 
- spring hiberante 集成出现异常 java.lang.ClassNotFoundException: org.hibernate.engine.SessionFactoryImplementor
		出现如题的异常是由于hibernate和spring集成时的的版本不一致所导致. 如下面,所示,如果你用的hibneate 4.0及以上版本,那么将会报错,因为这里用的事务管理是hibernate 3 ... 
随机推荐
- HDU--4705
			题目: Y 原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=4705 分析:树形dp的思想,枚举中间点. #include<iostream> ... 
- struts2的MVC模式
			MVC是一种架构型模式,它本身并不引入新的功能,只是用来指导我们改善应用程序的架构,使得应用的模型和视图相分离,从而得到更好的开发和维护效率. 在MVC模式中,应用程序被划分成了模型(Model).视 ... 
- Zabbix应用一:Zabbix安装
			1.准备zabbix依赖环境:LNMP 依赖包安装参考http://www.osyunwei.com/archives/10057.html. cmake安装mysql: cmake . -DCMAK ... 
- nltk_28Twitter情感分析模型
			sklearn实战-乳腺癌细胞数据挖掘(博客主亲自录制视频教程) https://study.163.com/course/introduction.htm?courseId=1005269003&a ... 
- CALayer属性:position和anchorPoint
			一.position和anchorPoint 1.简单介绍 CALayer有2个非常重要的属性:position和anchorPoint @property CGPoint position; 用来设 ... 
- RAC转换传统的通信
			///////////////////各种机制转信号/////////////////////////////// 1.UI事件 [self.logInButton rac_signalForCont ... 
- Spring @Transactional注解不回滚不起作用无效
			原文地址:http://www.cnblogs.com/wuxiaofeng/p/6819209.html 这几天在项目里面发现我使用@Transactional之后,抛了异常居然不回滚.后来终于 ... 
- activity 中获取控件的宽高
			1.第一种方式: TextView textview3 = findViewById(R.id.textview3); textView3.post(new Runnable() { @Overrid ... 
- Django 2.0.1 官方文档翻译:接下来读什么(page 14)
			接下来读什么(page 14) 现在你应该已经阅读了所有的(page1-13 )介绍材料,决定继续使用Django.我们仅仅做了简要的介绍(事实上,如果你阅读了前面所有的内容,也只是全部文档的5%.) ... 
- 分享自己新做的vim colorscheme
			把下面的内容保存成darkslategrey.vim,放入~/.vim/colors目录即可. " Vim color file " Maintainer: jiqing() &q ... 
