Hibernate 事务处理和spring中配置事务
2015-01-07 13:52
218 查看
原文链接:http://blog.csdn.net/sd0902/article/details/8393700
事务是指由一个或者多个SQL语句组成的工作单元,这个单元中SQL语句只要有一个SQL语句执行失败,就会撤销整个工作单元。
事务的成功取决于工作单元的所有SQL语句都执行成功,它必须具备ACID特征,ACID是Atomic(原子性)、Consistency(一致性)、Isolation(隔离性)和持久性(Durability),它们的含义是:
(1) 原子性:事务是不可分割的工作单元,事务中所有操作执行成功事务才算成功
(2) 一致性:事务不能破坏数据的完整性和一致性(正确性)
(3) 隔离性:在并发环境中,事务是独立的,它不依赖其他事务也能完成任务
(4) 持久性:只要事务成功执行,数据永久保存下来
2声明事务边界
数据库系统支持以下两种事务模式:
(1)自动提交模式:每一个SQL语句都是一个独立的事务,如果执行成功就自动提交,否之 自动回滚
(2)手工提交模式:由程序显式指定事务边界
在mysql.exe程序中声明事务
(1) 在自动提交模式下运行事务
每一个SQL语句就是一个独立的事务,由系统自动提交和回滚,如:
insert into ACCOUNTS values(1,’Tom’,10000)
(2) 手工提交模式下运行事务
手工提交模式,必须显式指定事务边界
1. 开始事务:begin
transaction
2. 提交事务:commit
transaction
3. 回滚(撤销)事务:rollback
transaction
如以下的银行转帐事务
begin transaction
set @errorSum=0
update bank set currentMoney=currentMoney-1000 where customerName=’张三’
set @errorSum=@errorSum+@@error--@@error是系统的全局变量.
update bank set currentMoney=currentMoney+1000 where customerName=’李四’
set @errorSum=@errorSum+@@error
if @errorSum<>0
rollback transaction
else
commit transaction
通过JDBC API声明事务边界
java.sq.Connection类提供了以下用于控制事务的方法
(1) setAutoCommit(boolean
autoCommit):设置是事自动提交事务
(2) commit():提交事务
(3) rollback():撤销事务
[java] view
plaincopy
try{
con.setAutoCommit(false);//设置为手工提交模式
stmt=con.createStatement();
stmt.executeUpdate(“update ACCOUNTS set BALANCE=1000-100 where ID=1”);
stmt.executeUpdate(update ACCOUNTS set BALANCE=0+100 where ID=2”)
con.commit();//提交事务
}catch(SQLException e){
con.rollback();//不成功就撤销事务.这语句也要捕获异常,代码略
}finally{
stmt.close();
con.close();//.这语句也要捕获异常,代码
}
通过Hibernate API声明事务边界
Hibernate API封装了JDBC
API和JTA API.应用程序可以绕过Hibernate
API直接通过 JDBC
API和JTA API来声明事务,但是这不利于跨平台开发
从SessionFactory中获得Session实例有两种方式:
(1)Session session=sessionFactory.openSession();//从连接池中获得连接,并把连接设为手 工提交事务模式
(2)Connection con=DriverManager.getConnection(url,user,pwd);//这种方式绕过Hibernate
con.setAutoCommit(false);
Session session=sessionFactory.openSession(con);
在Hibernate
API中,Session和Transaction类提供了以下声明事务的方法:
(1) Transaction
tx=session.beginTransaction();//开始事务
(2) tx.commit();//提交事务,调用flush()方法清理缓存,然后提交事务
(3) tx.rollback();//撤销事务
要注意的内容
1.尽量让一个Session对应一个事务,不管事务成功与否最后要关闭Sessin,让其清空 缓存,释放占用的连接;如果事务仅包含只读(select)操作,也应在执行成功后提交事务, 让数据库释放事务所占的资源.如:
[java] view
plaincopy
Session session=sessionFactory.openSession();
Transaction tx;
try{
tx=session.beginTransaction();//开始一个事务
….//执行一些操作
tx.commit();//提交事务
}catch(Exception e){
tx.rollback();//撤销事务。这个语句也要捕获异常,代码略
}finally{
session.close();//撤销事务。这个语句也要捕获异常,代码略
}
2.一个Session可以对应多个事务,这种方式优点中重用缓存中的持久化对象,如:
[java] view
plaincopy
try{
tx1=session.beginTransaction();
….//执行一些操作
tx1.commit();//提交事务
session.desconnect();//释放数据连接
….//执行一些操作,这些操作不属于任何事务
session.reconnnect();//重新获得数据库连接
tx2=session.beginTranction();//开始第二个事务
….// 执行一些操作
tx2.commit();//提交第二个事务
}catch(Exception e){
if(tx1!=null)tx1.rollback();
if(tx2!=null)tx2.rollback();
}finally{
session.close();
}
注意:在一个事务没提交之前,不可以开始第二个事务(不允许的);如果Session的一个 事务出现了异常,就应关闭这个Session。如果仍然用它执行其他事务是不可取的
[html]
view plaincopy
<?xml version="1.0" encoding="UTF-8"?>
<!-- 指定Spring配置文件的Schema信息 -->
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd"
default-autowire="byName">
<!-- 定义数据源Bean,使用C3P0数据源实现 -->
<!-- 设置连接数据库的驱动、URL、用户名、密码
连接池最大连接数、最小连接数、初始连接数等参数 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
destroy-method="close"
p:driverClass="com.mysql.jdbc.Driver"
p:jdbcUrl="jdbc:mysql://localhost:3306/sshweb?useUnicode=true&characterEncoding=utf-8"
p:user="root"
p:password="123456"
p:maxPoolSize="40"
p:minPoolSize="1"
p:initialPoolSize="1"
p:maxIdleTime="20"/>
<!-- 定义Hibernate的SessionFactory -->
<!-- 依赖注入数据源,注入正是上面定义的dataSource -->
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"
p:dataSource-ref="dataSource">
<!-- mappingResouces属性用来列出全部映射文件 -->
<!--<property name="mappingResources">
<list>
<value>com/model/Novel.hbm.xml</value>
<value>com/model/NovelType.hbm.xml</value>
</list>
</property>-->
<property name="mappingLocations">
<list>
<value>classpath:com/model/mapping/*.hbm.xml</value>
</list>
</property>
<!-- 定义Hibernate的SessionFactory的属性 -->
<property name="hibernateProperties">
<!-- 指定数据库方言、是否自动建表
是否生成SQL语句等 -->
<value>
hibernate.dialect=org.hibernate.dialect.MySQLDialect
hibernate.hbm2ddl.auto=update
hibernate.show_sql=true
hibernate.connection.characterEncoding=UTF-8
<!-- hibernate.format_sql=true-->
<!-- #开启二级缓存-->
<!-- hibernate.cache.use_second_level_cache=true-->
<!-- #设置二级缓存的提供者-->
<!-- hibernate.cache.provider_class=org.hibernate.cache.EhCacheProvider-->
</value>
</property>
</bean>
<!-- 配置Hibernate的局部事务管理器,使用HibernateTransactionManager类 -->
<!-- 该类实现PlatformTransactionManager接口,是针对Hibernate的特定实现-->
<!-- 并注入SessionFactory的引用 -->
<bean id="transactionManager" class=
"org.springframework.orm.hibernate3.HibernateTransactionManager"
p:sessionFactory-ref="sessionFactory"/>
<!-- 配置事务增强处理Bean,指定事务管理器 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<!-- 用于配置详细的事务语义 -->
<tx:attributes>
<!-- 所有以'get'开头的方法是read-only的 -->
<tx:method name="get*" read-only="true"/>
<!-- 其他方法使用默认的事务设置 -->
<tx:method name="*"/>
<!--不需要事务管理的-->
[html]
view plaincopy
<tx:method name="get*" read-only="false" propagation="NOT-SUPPORTED"/>
[html]
view plaincopy
</tx:attributes>
</tx:advice>
<aop:config proxy-target-class="true">
<!-- 配置一个切入点,匹配empManager和mgrManager
两个Bean的所有方法的执行 -->
<aop:pointcut id="pointcut"
expression="execution(* com.service.*.*(..))" />
<!-- 指定在leePointcut切入点应用txAdvice事务增强处理 -->
<aop:advisor advice-ref="txAdvice"
pointcut-ref="pointcut"/>
</aop:config>
<!-- 装配HibernateTemplate实例
<bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate">
<constructor-arg ref="sessionFactory"/>
</bean> -->
lt;/beans>
1.非集成spring事务管理
事务是指由一个或者多个SQL语句组成的工作单元,这个单元中SQL语句只要有一个SQL语句执行失败,就会撤销整个工作单元。
事务的成功取决于工作单元的所有SQL语句都执行成功,它必须具备ACID特征,ACID是Atomic(原子性)、Consistency(一致性)、Isolation(隔离性)和持久性(Durability),它们的含义是:
(1) 原子性:事务是不可分割的工作单元,事务中所有操作执行成功事务才算成功
(2) 一致性:事务不能破坏数据的完整性和一致性(正确性)
(3) 隔离性:在并发环境中,事务是独立的,它不依赖其他事务也能完成任务
(4) 持久性:只要事务成功执行,数据永久保存下来
2声明事务边界
数据库系统支持以下两种事务模式:
(1)自动提交模式:每一个SQL语句都是一个独立的事务,如果执行成功就自动提交,否之 自动回滚
(2)手工提交模式:由程序显式指定事务边界
在mysql.exe程序中声明事务
(1) 在自动提交模式下运行事务
每一个SQL语句就是一个独立的事务,由系统自动提交和回滚,如:
insert into ACCOUNTS values(1,’Tom’,10000)
(2) 手工提交模式下运行事务
手工提交模式,必须显式指定事务边界
1. 开始事务:begin
transaction
2. 提交事务:commit
transaction
3. 回滚(撤销)事务:rollback
transaction
如以下的银行转帐事务
begin transaction
set @errorSum=0
update bank set currentMoney=currentMoney-1000 where customerName=’张三’
set @errorSum=@errorSum+@@error--@@error是系统的全局变量.
update bank set currentMoney=currentMoney+1000 where customerName=’李四’
set @errorSum=@errorSum+@@error
if @errorSum<>0
rollback transaction
else
commit transaction
通过JDBC API声明事务边界
java.sq.Connection类提供了以下用于控制事务的方法
(1) setAutoCommit(boolean
autoCommit):设置是事自动提交事务
(2) commit():提交事务
(3) rollback():撤销事务
[java] view
plaincopy
try{
con.setAutoCommit(false);//设置为手工提交模式
stmt=con.createStatement();
stmt.executeUpdate(“update ACCOUNTS set BALANCE=1000-100 where ID=1”);
stmt.executeUpdate(update ACCOUNTS set BALANCE=0+100 where ID=2”)
con.commit();//提交事务
}catch(SQLException e){
con.rollback();//不成功就撤销事务.这语句也要捕获异常,代码略
}finally{
stmt.close();
con.close();//.这语句也要捕获异常,代码
}
通过Hibernate API声明事务边界
Hibernate API封装了JDBC
API和JTA API.应用程序可以绕过Hibernate
API直接通过 JDBC
API和JTA API来声明事务,但是这不利于跨平台开发
从SessionFactory中获得Session实例有两种方式:
(1)Session session=sessionFactory.openSession();//从连接池中获得连接,并把连接设为手 工提交事务模式
(2)Connection con=DriverManager.getConnection(url,user,pwd);//这种方式绕过Hibernate
con.setAutoCommit(false);
Session session=sessionFactory.openSession(con);
在Hibernate
API中,Session和Transaction类提供了以下声明事务的方法:
(1) Transaction
tx=session.beginTransaction();//开始事务
(2) tx.commit();//提交事务,调用flush()方法清理缓存,然后提交事务
(3) tx.rollback();//撤销事务
要注意的内容
1.尽量让一个Session对应一个事务,不管事务成功与否最后要关闭Sessin,让其清空 缓存,释放占用的连接;如果事务仅包含只读(select)操作,也应在执行成功后提交事务, 让数据库释放事务所占的资源.如:
[java] view
plaincopy
Session session=sessionFactory.openSession();
Transaction tx;
try{
tx=session.beginTransaction();//开始一个事务
….//执行一些操作
tx.commit();//提交事务
}catch(Exception e){
tx.rollback();//撤销事务。这个语句也要捕获异常,代码略
}finally{
session.close();//撤销事务。这个语句也要捕获异常,代码略
}
2.一个Session可以对应多个事务,这种方式优点中重用缓存中的持久化对象,如:
[java] view
plaincopy
try{
tx1=session.beginTransaction();
….//执行一些操作
tx1.commit();//提交事务
session.desconnect();//释放数据连接
….//执行一些操作,这些操作不属于任何事务
session.reconnnect();//重新获得数据库连接
tx2=session.beginTranction();//开始第二个事务
….// 执行一些操作
tx2.commit();//提交第二个事务
}catch(Exception e){
if(tx1!=null)tx1.rollback();
if(tx2!=null)tx2.rollback();
}finally{
session.close();
}
注意:在一个事务没提交之前,不可以开始第二个事务(不允许的);如果Session的一个 事务出现了异常,就应关闭这个Session。如果仍然用它执行其他事务是不可取的
2.集成spring事务管理
[html]view plaincopy
<?xml version="1.0" encoding="UTF-8"?>
<!-- 指定Spring配置文件的Schema信息 -->
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd"
default-autowire="byName">
<!-- 定义数据源Bean,使用C3P0数据源实现 -->
<!-- 设置连接数据库的驱动、URL、用户名、密码
连接池最大连接数、最小连接数、初始连接数等参数 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
destroy-method="close"
p:driverClass="com.mysql.jdbc.Driver"
p:jdbcUrl="jdbc:mysql://localhost:3306/sshweb?useUnicode=true&characterEncoding=utf-8"
p:user="root"
p:password="123456"
p:maxPoolSize="40"
p:minPoolSize="1"
p:initialPoolSize="1"
p:maxIdleTime="20"/>
<!-- 定义Hibernate的SessionFactory -->
<!-- 依赖注入数据源,注入正是上面定义的dataSource -->
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"
p:dataSource-ref="dataSource">
<!-- mappingResouces属性用来列出全部映射文件 -->
<!--<property name="mappingResources">
<list>
<value>com/model/Novel.hbm.xml</value>
<value>com/model/NovelType.hbm.xml</value>
</list>
</property>-->
<property name="mappingLocations">
<list>
<value>classpath:com/model/mapping/*.hbm.xml</value>
</list>
</property>
<!-- 定义Hibernate的SessionFactory的属性 -->
<property name="hibernateProperties">
<!-- 指定数据库方言、是否自动建表
是否生成SQL语句等 -->
<value>
hibernate.dialect=org.hibernate.dialect.MySQLDialect
hibernate.hbm2ddl.auto=update
hibernate.show_sql=true
hibernate.connection.characterEncoding=UTF-8
<!-- hibernate.format_sql=true-->
<!-- #开启二级缓存-->
<!-- hibernate.cache.use_second_level_cache=true-->
<!-- #设置二级缓存的提供者-->
<!-- hibernate.cache.provider_class=org.hibernate.cache.EhCacheProvider-->
</value>
</property>
</bean>
<!-- 配置Hibernate的局部事务管理器,使用HibernateTransactionManager类 -->
<!-- 该类实现PlatformTransactionManager接口,是针对Hibernate的特定实现-->
<!-- 并注入SessionFactory的引用 -->
<bean id="transactionManager" class=
"org.springframework.orm.hibernate3.HibernateTransactionManager"
p:sessionFactory-ref="sessionFactory"/>
<!-- 配置事务增强处理Bean,指定事务管理器 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<!-- 用于配置详细的事务语义 -->
<tx:attributes>
<!-- 所有以'get'开头的方法是read-only的 -->
<tx:method name="get*" read-only="true"/>
<!-- 其他方法使用默认的事务设置 -->
<tx:method name="*"/>
<!--不需要事务管理的-->
[html]
view plaincopy
<tx:method name="get*" read-only="false" propagation="NOT-SUPPORTED"/>
[html]
view plaincopy
</tx:attributes>
</tx:advice>
<aop:config proxy-target-class="true">
<!-- 配置一个切入点,匹配empManager和mgrManager
两个Bean的所有方法的执行 -->
<aop:pointcut id="pointcut"
expression="execution(* com.service.*.*(..))" />
<!-- 指定在leePointcut切入点应用txAdvice事务增强处理 -->
<aop:advisor advice-ref="txAdvice"
pointcut-ref="pointcut"/>
</aop:config>
<!-- 装配HibernateTemplate实例
<bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate">
<constructor-arg ref="sessionFactory"/>
</bean> -->
lt;/beans>
相关文章推荐
- Spring整合Hibernate时,配置事务处理
- Hibernate 事务处理和spring中配置事务
- spring2.5 hibernate 配置最少的事务处理(声明切面)
- Hibernate 事务处理和spring中配置事务
- spring 配置hibernate事务处理
- 在Spring中配置Hibernate事务
- struts+hibernate+spring事务配置
- hibernate3.0+ejb3 annotaion配置实战+spring1.21 annotation事务控制
- struts + spring + hibernate整合事务配置的问题(请教高手)
- spring 同时配置hibernate and jdbc 事务
- spring2.5 struts2 hibernate3 时事务配置注意的问题 openSessionInViewFilter web.xml
- Spring的四种声明式事务的配置-Hibernate事务
- spring 与 hibernate 及事务的配置
- hibernate整合进spring后的事务处理
- spring+hibernate+jpa配置JTA事务出错,如何解决?
- spring+hibernate事务配置最简单的方式
- SSH配置中Spring对Hib的自动事务处理
- Spring的四种声明式事务的配置-Hibernate事务
- struts+hibernate+spring事务配置
- Spring+Hibernate延迟和声明式事务处理最终解决方案