Hibernate 事務處理和spring中配置事務
原文連結:http://blog.csdn.net/sd0902/article/details/8393700
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 @[email protected][email protected]@[email protected]@error
update bank set currentMoney=currentMoney+1000 where customerName=’李四’
set @[email protected][email protected]@error
if @errorSum<>0
rollback transaction
else
commit transaction
通過JDBC API宣告事務邊界
java.sq.Connection類提供了以下用於控制事務的方法
(1) setAutoCommit(boolean autoCommit):設定是事自動提交事務
(2) commit():提交事務
(3) rollback():撤銷事務
- 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)操作,也應在執行成功後提交事務, 讓資料庫釋放事務所佔的資源.如:
- Session session=sessionFactory.openSession();
- Transaction tx;
- try{
- tx=session.beginTransaction();//開始一個事務
- ….//執行一些操作
- tx.commit();//提交事務
- }catch(Exception e){
- tx.rollback();//撤銷事務。這個語句也要捕獲異常,程式碼略
- }finally{
- session.close();//撤銷事務。這個語句也要捕獲異常,程式碼略
- }
2.一個Session可以對應多個事務,這種方式優點中重用快取中的持久化物件,如:
- 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事務管理
- <?xmlversion="1.0"encoding="UTF-8"?>
- <!-- 指定Spring配置檔案的Schema資訊 -->
- <beansxmlns="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、使用者名稱、密碼
- 連線池最大連線數、最小連線數、初始連線數等引數 -->
- <beanid="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 -->
- <beanid="sessionFactory"
- class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"
- p:dataSource-ref="dataSource">
- <!-- mappingResouces屬性用來列出全部對映檔案 -->
- <!--<propertyname="mappingResources">
- <list>
- <value>com/model/Novel.hbm.xml</value>
- <value>com/model/NovelType.hbm.xml</value>
- </list>
- </property>-->
- <propertyname="mappingLocations">
- <list>
- <value>classpath:com/model/mapping/*.hbm.xml</value>
- </list>
- </property>
- <!-- 定義Hibernate的SessionFactory的屬性 -->
- <propertyname="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的引用 -->
- <beanid="transactionManager"class=
- "org.springframework.orm.hibernate3.HibernateTransactionManager"
- p:sessionFactory-ref="sessionFactory"/>
- <!-- 配置事務增強處理Bean,指定事務管理器 -->
- <tx:adviceid="txAdvice"transaction-manager="transactionManager">
- <!-- 用於配置詳細的事務語義 -->
- <tx:attributes>
- <!-- 所有以'get'開頭的方法是read-only的 -->
- <tx:methodname="get*"read-only="true"/>
- <!-- 其