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 ...
随机推荐
- 【bzoj2741】[FOTILE模拟赛] L
Portal --> bzoj2741 Solution 突然沉迷分块不能自拔 考虑用分块+可持久化trie来解决这个问题 对于每一块的块头\(L\),预处理\([L,i]\)区间内的所有子区间 ...
- 适用于vue项目的打印插件
此方法只适用于现代浏览器,IE10以下就别用了 // 使用时请尽量在nickTick中调用此方法 //打印 export default (refs, cb) => { let cloneN i ...
- 【转】了解CNN
摘要 过去几年,深度学习在解决诸如视觉识别.语音识别和自然语言处理等很多问题方面都表现出色.在不同类型的神经网络当中,卷积神经网络是得到最深入研究的.早期由于缺乏训练数据和计算能力,要在不产生过拟合的 ...
- 执行composer install后报错:执行composer install后报错: d11wtq/boris v1.0.10 requires ext-pcntl * -> the requested PHP extension pcntl is missing from your system.
执行composer install后报错: d11wtq/boris v1.0.10 requires ext-pcntl * -> the requested PHP extension p ...
- R语言数据整理
基本操作 读入csv数据 data <- read.csv("D:/Project/180414/data.csv", header = TRUE) 写出csv数据 writ ...
- 设置CMD默认路径
用CMD每一次都得切换路径,很麻烦. 所以,需要设置一下CMD默认路径: 1.打开注册表编辑器(WIN+R打开运行.输入regedit) 2.定位到: “HKEY_CURRENT_USER\Softw ...
- java抽象类和普通类的区别
1.抽象类不能被实例化. 2.抽象类可以有构造函数,被继承时子类必须继承父类一个构造方法,抽象方法不能被声明为静态. 3.抽象方法只需申明,而无需实现,抽象类中可以允许普通方法有主体 4.含有抽象方法 ...
- 非常强力的reduce
Array 的方法 reduce 是一个有非常多用处的函数. 它一个非常具有代表性的作用是将一个数组转换成一个值.但是你可以用它来做更多的事. 1.使用"reduce"代替&quo ...
- ASP.NET对无序列表批量操作的三种方法
在网页开发中,经常要用到无序列表.事实上在符合W3C标准的div+css布局中,无序列表被大量使用,ASP.NET虽然内置了BulletedList控件,用于创建和操作无序列表,但感觉不太好用.本篇介 ...
- petri网初步
历史:Petri网的概念是德国的Carl Adam Petri早在1962年提出来的.他在他的论文里提出了一个新的信息流模型,这个模型基于系统各部分的异步并发的操作,并把各部分之间的关系用网状的图来描 ...