1. 程式人生 > >Hibernate 事務處理和spring中配置事務

Hibernate 事務處理和spring中配置事務

原文連結:http://blog.csdn.net/sd0902/article/details/8393700

1.非整合spring事務管理

事務是指由一個或者多個SQL語句組成的工作單元,這個單元中SQL語句只要有一個SQL語句執行失敗,就會撤銷整個工作單元。

 事務的成功取決於工作單元的所有SQL語句都執行成功,它必須具備ACID特徵,ACIDAtomic(原子性)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():撤銷事務

  1. try{  
  2. con.setAutoCommit(false);//設定為手工提交模式
  3. stmt=con.createStatement();  
  4. stmt.executeUpdate(“update ACCOUNTS set BALANCE=1000-100 where ID=1”);  
  5. stmt.executeUpdate(update ACCOUNTS set BALANCE=0+100 where ID=2”)  
  6. con.commit();//提交事務
  7. }catch(SQLException e){  
  8.        con.rollback();//不成功就撤銷事務.這語句也要捕獲異常,程式碼略
  9. }finally{  
  10.        stmt.close();  
  11.        con.close();//.這語句也要捕獲異常,程式碼
  12. }  

通過Hibernate API宣告事務邊界

 Hibernate API封裝了JDBC APIJTA API.應用程式可以繞過Hibernate API直接通過 JDBC APIJTA 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,SessionTransaction類提供了以下宣告事務的方法:

(1) Transaction tx=session.beginTransaction();//開始事務

(2) tx.commit();//提交事務,呼叫flush()方法清理快取,然後提交事務

(3) tx.rollback();//撤銷事務

 要注意的內容

 1.儘量讓一個Session對應一個事務,不管事務成功與否最後要關閉Sessin,讓其清空 快取,釋放佔用的連線;如果事務僅包含只讀(select)操作,也應在執行成功後提交事務, 讓資料庫釋放事務所佔的資源.: 

  1. Session session=sessionFactory.openSession();  
  2.        Transaction tx;  
  3.        try{  
  4.               tx=session.beginTransaction();//開始一個事務
  5.               ….//執行一些操作
  6.               tx.commit();//提交事務
  7.        }catch(Exception e){  
  8.               tx.rollback();//撤銷事務。這個語句也要捕獲異常,程式碼略
  9.        }finally{  
  10.               session.close();//撤銷事務。這個語句也要捕獲異常,程式碼略
  11.        }  

 2.一個Session可以對應多個事務,這種方式優點中重用快取中的持久化物件,如:

  1. try{  
  2.             tx1=session.beginTransaction();  
  3.             ….//執行一些操作
  4.             tx1.commit();//提交事務
  5.             session.desconnect();//釋放資料連線
  6.             ….//執行一些操作,這些操作不屬於任何事務
  7.             session.reconnnect();//重新獲得資料庫連線
  8.             tx2=session.beginTranction();//開始第二個事務
  9.             ….// 執行一些操作
  10.             tx2.commit();//提交第二個事務
  11.      }catch(Exception e){  
  12.             if(tx1!=null)tx1.rollback();  
  13.             if(tx2!=null)tx2.rollback();  
  14.      }finally{  
  15.             session.close();  
  16.      }  

 注意:在一個事務沒提交之前,不可以開始第二個事務(不允許的);如果Session的一個 事務出現了異常,就應關閉這個Session。如果仍然用它執行其他事務是不可取的

2.整合spring事務管理

  1. <?xmlversion="1.0"encoding="UTF-8"?>
  2. <!-- 指定Spring配置檔案的Schema資訊 -->
  3. <beansxmlns="http://www.springframework.org/schema/beans"
  4.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  5.     xmlns:aop="http://www.springframework.org/schema/aop"
  6.     xmlns:p="http://www.springframework.org/schema/p"
  7.     xmlns:tx="http://www.springframework.org/schema/tx"
  8.     xsi:schemaLocation="http://www.springframework.org/schema/beans   
  9.     http://www.springframework.org/schema/beans/spring-beans-3.0.xsd  
  10.     http://www.springframework.org/schema/tx   
  11.     http://www.springframework.org/schema/tx/spring-tx-3.0.xsd  
  12.     http://www.springframework.org/schema/aop   
  13.     http://www.springframework.org/schema/aop/spring-aop-3.0.xsd"  
  14.     default-autowire="byName">
  15.     <!-- 定義資料來源Bean,使用C3P0資料來源實現 -->
  16.     <!-- 設定連線資料庫的驅動、URL、使用者名稱、密碼  
  17.         連線池最大連線數、最小連線數、初始連線數等引數 -->
  18.     <beanid="dataSource"class="com.mchange.v2.c3p0.ComboPooledDataSource"
  19.         destroy-method="close"
  20.         p:driverClass="com.mysql.jdbc.Driver"
  21.         p:jdbcUrl="jdbc:mysql://localhost:3306/sshweb?useUnicode=true&characterEncoding=utf-8"
  22.         p:user="root"
  23.         p:password="123456"
  24.         p:maxPoolSize="40"
  25.         p:minPoolSize="1"
  26.         p:initialPoolSize="1"
  27.         p:maxIdleTime="20"/>
  28.     <!-- 定義Hibernate的SessionFactory -->
  29.     <!-- 依賴注入資料來源,注入正是上面定義的dataSource -->
  30.     <beanid="sessionFactory"
  31.         class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"
  32.         p:dataSource-ref="dataSource">
  33.         <!-- mappingResouces屬性用來列出全部對映檔案 -->
  34.         <!--<propertyname="mappingResources">
  35.             <list>
  36.                 <value>com/model/Novel.hbm.xml</value>
  37.                 <value>com/model/NovelType.hbm.xml</value>
  38.             </list>
  39.         </property>-->
  40.         <propertyname="mappingLocations">
  41.             <list>
  42.                  <value>classpath:com/model/mapping/*.hbm.xml</value>
  43.             </list>
  44.         </property>
  45.         <!-- 定義Hibernate的SessionFactory的屬性 -->
  46.         <propertyname="hibernateProperties">
  47.             <!-- 指定資料庫方言、是否自動建表  
  48.                 是否生成SQL語句等  -->
  49.             <value>
  50.             hibernate.dialect=org.hibernate.dialect.MySQLDialect  
  51.             hibernate.hbm2ddl.auto=update
  52.             hibernate.show_sql=true
  53.             hibernate.connection.characterEncoding=UTF-8  
  54. <!--         hibernate.format_sql=true-->
  55. <!--         #開啟二級快取-->
  56. <!--         hibernate.cache.use_second_level_cache=true-->
  57. <!--         #設定二級快取的提供者-->
  58. <!--         hibernate.cache.provider_class=org.hibernate.cache.EhCacheProvider-->
  59.             </value>
  60.         </property>
  61.     </bean>
  62.     <!-- 配置Hibernate的區域性事務管理器,使用HibernateTransactionManager類 -->
  63.     <!-- 該類實現PlatformTransactionManager介面,是針對Hibernate的特定實現-->
  64.     <!-- 並注入SessionFactory的引用 -->
  65.     <beanid="transactionManager"class=  
  66.         "org.springframework.orm.hibernate3.HibernateTransactionManager"
  67.         p:sessionFactory-ref="sessionFactory"/>
  68.     <!-- 配置事務增強處理Bean,指定事務管理器 -->
  69.     <tx:adviceid="txAdvice"transaction-manager="transactionManager">
  70.         <!-- 用於配置詳細的事務語義 -->
  71.         <tx:attributes>
  72.             <!-- 所有以'get'開頭的方法是read-only的 -->
  73.             <tx:methodname="get*"read-only="true"/>
  74.             <!-- 其