Hibernate事务管理
User类:
public class User implements Serializable{
public User(){}
private Integer id;
private String name;
private Integer age;
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 Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
User.hbm.xml:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" > <hibernate-mapping>
<class name="com.po.User"
table="TEST_USER">
<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="age"
column="age"
type="java.lang.Integer"
not-null="true"
unique="false"
length="0"/>
</class>
</hibernate-mapping>
hibernate.cfg.xml:
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/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:@192.168.58.1:1521:123
</property>
<property name="hibernate.connection.username">123</property>
<property name="hibernate.connection.password">123</property>
<property name="dialect">org.hibernate.dialect.OracleDialect</property> <mapping resource="com/po/User.hbm.xml"/>
</session-factory>
</hibernate-configuration>
测试类:
public class Test {
public static void main(String[] args) {
User user = new User();
user.setId(1);
user.setName("111");
user.setAge(10);
Configuration conf = new Configuration().configure();
SessionFactory sf = conf.buildSessionFactory();
Session sess = sf.openSession();
Transaction t = sess.beginTransaction();//说明一
try{
sess.save(user);
t.commit();//说明二
}catch(Exception e){
t.rollback();
}finally{
if(sess.isOpen()){
sess.close();
}
}
}
}
说明一:Hibernate本身不具有事务管理能力,而是对底层JDBC事务或JTA事务的轻量级封装
org.hibernate.impl.SessionImpl类(该类是会话的实现类):
public Transaction beginTransaction() throws HibernateException {
errorIfClosed();
if ( rootSession != null ) {
log.warn( "Transaction started on non-root session" );
}
Transaction result = getTransaction();
result.begin();
return result;
}
public Transaction getTransaction() throws HibernateException {
errorIfClosed();
return jdbcContext.getTransaction();
}
org.hibernate.jdbc.JDBCContext类:
public Transaction getTransaction() throws HibernateException {
if (hibernateTransaction==null) {
hibernateTransaction = owner.getFactory().getSettings()
.getTransactionFactory().createTransaction( this, owner );
}
return hibernateTransaction;
}
TransactionFactory有很多实现类:
选择最基本的org.hibernate.transaction.JDBCTransactionFactory观察一下:
public Transaction createTransaction(JDBCContext jdbcContext, Context transactionContext)throws HibernateException {
return new JDBCTransaction( jdbcContext, transactionContext );
}
org.hibernate.transaction.JDBCTransaction类的说明:
Transaction implementation based on transaction management through a JDBC Connection.
This the Hibernate's default transaction strategy.
事务开始时,会禁用自动提交:
public void begin() throws HibernateException {
if (begun) {
return;
}
if (commitFailed) {
throw new TransactionException("cannot re-start transaction after failed commit");
}
log.debug("begin");
try {
toggleAutoCommit = jdbcContext.connection().getAutoCommit();
if ( log.isDebugEnabled() ) {
log.debug("current autocommit status: " + toggleAutoCommit);
}
if (toggleAutoCommit) {
log.debug("disabling autocommit");
jdbcContext.connection().setAutoCommit(false);//right here
}
}
catch (SQLException e) {
log.error("JDBC begin failed", e);
throw new TransactionException("JDBC begin failed: ", e);
}
callback = jdbcContext.registerCallbackIfNecessary();
begun = true;
committed = false;
rolledBack = false;
if ( timeout>0 ) {
jdbcContext.getConnectionManager().getBatcher().setTransactionTimeout(timeout);
}
jdbcContext.afterTransactionBegin(this);
}
打开log日志也能看出很多端倪:
[2013-08-09 16:37:55] DEBUG -> begin
[2013-08-09 16:37:55] DEBUG -> opening JDBC connection
[2013-08-09 16:37:55] DEBUG -> current autocommit status: false
[2013-08-09 16:37:55] DEBUG -> generated identifier: 1, using strategy: org.hibernate.id.Assigned
[2013-08-09 16:37:55] DEBUG -> commit
说明二:不需要显式的调用flush()方法,事务提交时会根据session的FlushMode自动触发session的flush
还是通过最基本的JDBCTransaction类看一下:
事务提交完成之后又恢复了事务的自动提交
public void commit() throws HibernateException {
if (!begun) {
throw new TransactionException("Transaction not successfully started");
}
log.debug("commit");
if ( !transactionContext.isFlushModeNever() && callback ) {
transactionContext.managedFlush(); //根据FlushMode刷新Session
notifySynchronizationsBeforeTransactionCompletion();
if ( callback ) {
jdbcContext.beforeTransactionCompletion( this );
}
try {
commitAndResetAutoCommit();//look here
log.debug("committed JDBC Connection");
committed = true;
if ( callback ) {
jdbcContext.afterTransactionCompletion( true, this );
}
notifySynchronizationsAfterTransactionCompletion( Status.STATUS_COMMITTED );
}
catch (SQLException e) {
log.error("JDBC commit failed", e);
commitFailed = true;
if ( callback ) {
jdbcContext.afterTransactionCompletion( false, this );
}
notifySynchronizationsAfterTransactionCompletion( Status.STATUS_UNKNOWN );
throw new TransactionException("JDBC commit failed", e);
}
finally {
closeIfRequired();
}
}
private void commitAndResetAutoCommit() throws SQLException {
try {
jdbcContext.connection().commit();
}
finally {
toggleAutoCommit();
}
}
private void toggleAutoCommit() {
try {
if (toggleAutoCommit) {
log.debug("re-enabling autocommit");
jdbcContext.connection().setAutoCommit( true );//重置了自动提交
}
}
catch (Exception sqle) {
log.error("Could not toggle autocommit", sqle);
//swallow it (the transaction _was_ successful or successfully rolled back)
}
}
JDBC事务默认自动提交,Hibernate编程式事务管理当然要关闭自动提交,最后手动提交
Hibernate事务管理的更多相关文章
- hibernate事务管理 (jdbc jta)
hibernate的两种事务管理jdbc 和jta方式.下边说说两者的区别一.说明一下jdbc和jta方式事务管理的区别:JDBC事务由Connnection管理,也就是说,事务管理实际上是在JDBC ...
- (转)Hibernate事务管理
Hibernate的事务管理 事务(Transaction)是工作中的基本逻辑单位,可以用于确保数据库能够被正确修改,避免数据只修改了一部分而导致数据不完整,或者在修改时受到用户干扰.作为一名软件设计 ...
- Hibernate 事务管理
一. 事务包含四个基本特性:简称ACID: 1. Atomic(原子性):全部成功或全部失败: 2. Consistency(一致性):只有合法数据才能被写入,不合法则回滚到最初状态: 3. Isol ...
- Spring对Hibernate事务管理
谈Spring事务管理之前我们想一下在我们不用Spring的时候,在Hibernate中我们是怎么进行数据操作的.在Hibernate中 我们每次进行一个操作的的时候我们都是要先开启事务,然后进行数据 ...
- Spring与Hibernate整合,实现Hibernate事务管理
1.所需的jar包 连接池/数据库驱动包 Hibernate相关jar Spring 核心包(5个) Spring aop 包(4个) spring-orm-3.2.5.RELEASE.jar ...
- Spring对Hibernate事务管理【转】
在谈Spring事务管理之前我们想一下在我们不用Spring的时候,在Hibernate中我们是怎么进行数据操作的.在Hibernate中我们每次进行一个操作的的时候我们都是要先开启事务,然后进行数据 ...
- Hibernate事务管理-HibernateTransactionManager-对hibernate session的管理
由于对SSH还停留在比较初级的应用水平上,今天在遇到一个疑惑时折腾了很久,具体问题是这样的, 有这么一个测试方法, public static void test1() { ApplicationCo ...
- Spring中配置Hibernate事务管理
<!-- transationManager --> <bean id="transactionManager" class="org.springfr ...
- Hibernate框架笔记02_主键生成策略_一级缓存_事务管理
目录 0. 结构图 1. 持久化类的编写规则 1.1 持久化和持久化类 1.2 持久化类的编写规则 2. 主键生成策略 2.1 主键的分类 2.2 主键生成策略 3. 持久化类的三种状态[了解] 3. ...
随机推荐
- EF双向一对一中的坑
EF版本 6.0 在项目中双向一对一关系是普遍存在的,如果不仔细检查,并不容易发现这个坑 下面新建两个类(假设这两个类是一对一的关系)对应实体都设置为可延迟加载 映射关系为: 再建一个数据访问类: 运 ...
- c程序设计语言_习题1-9_将输入流复制到输出流,并将多个空格过滤成一个空格
Write a program to copy its input to its output, replacing each string of one or more blanks by a si ...
- HUFFMAN 树
在一般的数据结构的书中,树的那章后面,著者一般都会介绍一下哈夫曼(HUFFMAN) 树和哈夫曼编码.哈夫曼编码是哈夫曼树的一个应用.哈夫曼编码应用广泛,如 JPEG中就应用了哈夫曼编码. 首先介绍什么 ...
- Spring mvc get和post传值乱码问题
1.url拼值 传单值 对象 list map都是用json的格式传入后台 <%@ page language="java" contentType="text/ ...
- BestCoder Round #81 (div.2) B Matrix
B题...水题,记录当前行是由原矩阵哪行变来的. #include<cstdio> #include<cstring> #include<cstdlib> #inc ...
- tmux快捷键`
Ctrl+b 激活控制台:此时以下按键生效 系统操作 ? 列出所有快捷键:按q返回 d 脱离当前会话:这样可以暂时返回Shell界面,输入tmux attach能够重新进入之前的会话 D 选择要脱离的 ...
- Linux下platform设备以及platform设备和驱动注册的先后顺序
platform是Linux系统提供的一种管理设备的手段,所有SOC系统中集成的独立的外设控制器.挂接在SOC内存空间的外设等都属Platform设备.如ARM S3C6410处理器中,把内部集成的I ...
- Spark在集群中的安装
今天由于所以要安装spark做一些实验.我已有的环境是: 操作系统:CentOS6.5 hadoop:hadoop2.4.1 JDK:1.7 集群环境:四个节点 闲话不说,以下是我的安装步骤: 说 ...
- ubuntu下安装opencv 2.4.9 脚本,支持摄像头和cuda
arch=$(uname -m) if [ "$arch" == "i686" -o "$arch" == "i386" ...
- 【原创】关于hashcode和equals的不同实现对HashMap和HashSet集合类的影响的探究
这篇文章做了一个很好的测试:http://blog.csdn.net/afgasdg/article/details/6889383,判断往HashSet(不允许元素重复)里塞对象时,是如何判定set ...