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. ...
随机推荐
- [Hadoop源码解读](五)MapReduce篇之Writable相关类
前面讲了InputFormat,就顺便讲一下Writable的东西吧,本来应当是放在HDFS中的. 当要在进程间传递对象或持久化对象的时候,就需要序列化对象成字节流,反之当要将接收到或从磁盘读取的字节 ...
- bzoj3039
经典题目不多说 ..,..] of longint; l,r:..] of longint; i,j,n,m,ans:longint; x:char; function max ...
- mac 软件安装
[Mac]PS CC 软件下载及破解的详细方法 为github帐号添加SSH keys 在mac下,打开文件都是“Smart Adobe CC Blocker v1.0”已损坏,打不开 brew ma ...
- JQuery datepicker 用法
JQuery datepicker 用法 jQuery UI很强大,其中的日期选择插件Datepicker是一个配置灵活的插件,我们可以自定义其展示方式,包括日期格式.语言.限制选择日期范围.添加 ...
- htmlparser 精确提取的一些代码
一. ConnectionManager manager = Page.getConnectionManager(); Parser parser = new Parser(manager .open ...
- java CopyOnWriteArrayList的使用
除了加锁外,其实还有一种方式可以防止并发修改异常,这就是将读写分离技术(不是数据库上的). 先回顾一下一个常识: 1.JAVA中“=”操作只是将引用和某个对象关联,假如同时有一个线程将引用指向另外一个 ...
- Unity3D Mathf函数
Mathf.Abs绝对值 计算并返回指定参数 f 绝对值. Mathf.Acos反余弦 static function Acos (f : float) : float 以弧度为单位计算并返回参数 f ...
- 数据挖掘R与SQL
本文在Creative Commons许可证下发布 对于数据挖掘专业网站 KDnuggets网站的Poll持保留态度,但它的结果毕竟代表了某一类人群的使用偏好,尤其是在语言角度. 我们看排名前5位的语 ...
- ubuntu14.04安装opencv3.0
sudo apt-get update sudo apt-get upgrade 搭建C/C++编译环境: sudo apt-get install build-essential 安装关联库: su ...
- 《Genesis-3D开源游戏引擎--横版格斗游戏制作教程04:技能的输入与检测》
4.技能的输入与检测 概述: 技能系统的用户体验,制约着玩家对整个游戏的体验.游戏角色的技能华丽度,连招的顺利过渡,以及逼真的打击感,都作为一款游戏的卖点吸引着玩家的注意.开发者在开发游戏初期,会根据 ...