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事务管理的更多相关文章

  1. hibernate事务管理 (jdbc jta)

    hibernate的两种事务管理jdbc 和jta方式.下边说说两者的区别一.说明一下jdbc和jta方式事务管理的区别:JDBC事务由Connnection管理,也就是说,事务管理实际上是在JDBC ...

  2. (转)Hibernate事务管理

    Hibernate的事务管理 事务(Transaction)是工作中的基本逻辑单位,可以用于确保数据库能够被正确修改,避免数据只修改了一部分而导致数据不完整,或者在修改时受到用户干扰.作为一名软件设计 ...

  3. Hibernate 事务管理

    一. 事务包含四个基本特性:简称ACID: 1. Atomic(原子性):全部成功或全部失败: 2. Consistency(一致性):只有合法数据才能被写入,不合法则回滚到最初状态: 3. Isol ...

  4. Spring对Hibernate事务管理

    谈Spring事务管理之前我们想一下在我们不用Spring的时候,在Hibernate中我们是怎么进行数据操作的.在Hibernate中 我们每次进行一个操作的的时候我们都是要先开启事务,然后进行数据 ...

  5. Spring与Hibernate整合,实现Hibernate事务管理

    1.所需的jar包 连接池/数据库驱动包 Hibernate相关jar Spring 核心包(5个) Spring aop 包(4个) spring-orm-3.2.5.RELEASE.jar     ...

  6. Spring对Hibernate事务管理【转】

    在谈Spring事务管理之前我们想一下在我们不用Spring的时候,在Hibernate中我们是怎么进行数据操作的.在Hibernate中我们每次进行一个操作的的时候我们都是要先开启事务,然后进行数据 ...

  7. Hibernate事务管理-HibernateTransactionManager-对hibernate session的管理

    由于对SSH还停留在比较初级的应用水平上,今天在遇到一个疑惑时折腾了很久,具体问题是这样的, 有这么一个测试方法, public static void test1() { ApplicationCo ...

  8. Spring中配置Hibernate事务管理

    <!-- transationManager --> <bean id="transactionManager" class="org.springfr ...

  9. Hibernate框架笔记02_主键生成策略_一级缓存_事务管理

    目录 0. 结构图 1. 持久化类的编写规则 1.1 持久化和持久化类 1.2 持久化类的编写规则 2. 主键生成策略 2.1 主键的分类 2.2 主键生成策略 3. 持久化类的三种状态[了解] 3. ...

随机推荐

  1. poj1947Rebuilding Roads(树形DP)

    链接 刚接触 树上背包..有点抽象化 找好父亲和儿子的关系 及状态转移方程 代码里有详细的注释  就不解释了 #include <iostream> #include<cstdio& ...

  2. BILL.WEI]stimulsoft reports 中panel 妙用

    我们在通过stimulsoft reports做报表,有的时候,我们需要通过合并报表的一些中间列元素,我们就可以用到panel组件 如下图,我们需要合并报表中间项,一般手段达不到要求,只能通过嵌套pa ...

  3. Nginx反向代理+DNS轮询+IIS7.5 千万PV 百万IP 双线 网站架构案例

    原文地址:http://www.jb51.net/article/31844.htm Nginx  ("engine x") 是一个高性能的 HTTP 和反向代理服务器,也是一个 ...

  4. 【原】spark-submit提交应用程序的内部流程

    我们经常通过spark-submit来提交spark应用程序,那么让我们一起看一下这里面到底发生了什么吧. 知识点: 1.CLI命令行界面启动Spark应用程序 Unix有两种方式:1)spark-s ...

  5. oracle 对象上锁,不能插入或删除情况

    ora-00054:resource busy and acquire with nowait specified解决方法 当某个数据库用户在数据库中插入.更新.删除一个表的数据,或者增加一个表的主键 ...

  6. allegro

    ALLEGRO5的渲染部分低层使用了opengl或d3d加速.

  7. POJ1159 - Palindrome(区间DP)

    题目大意 给定一个字符串S,问最少插入多少个字符可以使字符串S变为回文串 题解 用dp[i][j]表示把字符串s[i-j]变为回文串需要插入的最小字符数 如果s[i]==s[j]那么dp[i][j]= ...

  8. 把普通的git库变成bare库

    $ cd your_repo $ mv .git .. && rm -fr * $ mv ../.git . $ mv .git/* . $ rmdir .git $ git conf ...

  9. weekend110(Hadoop)的 第一天笔记

    (2015年1月10日) 课程目录 01-hadoop职位需求状况 02-hadoop课程安排 03-hadoop应用场景 04-hadoop对海量数据处理的解决思路 05-hadoop版本选择和伪分 ...

  10. Spark源码的编译过程详细解读(各版本)

    说在前面的话   重新试多几次.编译过程中会出现下载某个包的时间太久,这是由于连接网站的过程中会出现假死,按ctrl+c,重新运行编译命令. 如果出现缺少了某个文件的情况,则要先清理maven(使用命 ...