面試題整理--開發中實現spring的事務有5種方式
阿新 • • 發佈:2019-01-24
Spring+Hibernate的實質:
就是把Hibernate用到的資料來源Datasource,Hibernate的SessionFactory例項,事務管理器HibernateTransactionManager,都交給Spring管理。
那麼再沒整合之前Hibernate是如何實現事務管理的呢?
通過ServletFilter實現資料庫事務的管理,這樣就避免了在資料庫操作中每次都要進行資料庫事務處理。
一.事務的4個特性:
原子性:一個事務中所有對資料庫的操作是一個不可分割的操作序列,要麼全做,要麼全部做。
一致性:資料不會因為事務的執行而遭到破壞。
隔離性:一個事務的執行,不受其他事務(程序)的干擾。既併發執行的個事務之間互不干擾。
永續性:一個事務一旦提交,它對資料庫的改變將是永久的。
二.事務的實現方式:
實現方式共有兩種:編碼方式;宣告式事務管理方式。
基於AOP技術實現的宣告式事務管理,實質就是:在方法執行前後進行攔截,然後在目標方法開始之前建立並加入事務,執行完目標方法後根據執行情況提交或回滾事務。
宣告式事務管理又有兩種方式:基於XML配置檔案的方式;另一個是在業務方法上進行@Transactional註解,將事務規則應用到業務邏輯中。
三.建立事務的時機:
是否需要建立事務,是由事務傳播行為控制的。讀資料不需要或只為其指定只讀事務,而資料的插入,修改,刪除就需要事務管理了。
Spring 配置檔案中關於事務配置總是由三個組成部分,分別是DataSource、TransactionManager和代理機制這三部分,無論哪種配置方式,一般變化的只是代理機制這部分。
都有一個代理
就是把Hibernate用到的資料來源Datasource,Hibernate的SessionFactory例項,事務管理器HibernateTransactionManager,都交給Spring管理。
那麼再沒整合之前Hibernate是如何實現事務管理的呢?
通過ServletFilter實現資料庫事務的管理,這樣就避免了在資料庫操作中每次都要進行資料庫事務處理。
一.事務的4個特性:
原子性:一個事務中所有對資料庫的操作是一個不可分割的操作序列,要麼全做,要麼全部做。
一致性:資料不會因為事務的執行而遭到破壞。
隔離性:一個事務的執行,不受其他事務(程序)的干擾。既併發執行的個事務之間互不干擾。
永續性:一個事務一旦提交,它對資料庫的改變將是永久的。
二.事務的實現方式:
實現方式共有兩種:編碼方式;宣告式事務管理方式。
基於AOP技術實現的宣告式事務管理,實質就是:在方法執行前後進行攔截,然後在目標方法開始之前建立並加入事務,執行完目標方法後根據執行情況提交或回滾事務。
宣告式事務管理又有兩種方式:基於XML配置檔案的方式;另一個是在業務方法上進行@Transactional註解,將事務規則應用到業務邏輯中。
三.建立事務的時機:
是否需要建立事務,是由事務傳播行為控制的。讀資料不需要或只為其指定只讀事務,而資料的插入,修改,刪除就需要事務管理了。
Spring
DataSource、TransactionManager這兩部分只是會根據資料訪問方式有所變化,比如使用Hibernate進行資料訪問時,DataSource實際為SessionFactory,TransactionManager的實現為HibernateTransactionManager。
具體如下圖:
根據代理機制的不同,總結了五種Spring事務的配置方式,配置檔案如下:
第一種方式:每個Bean
- <beanid="sessionFactory"
- class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
- <propertyname="configLocation"value="classpath:hibernate.cfg.xml"/>
- <propertyname="configurationClass"value="org.hibernate.cfg.AnnotationConfiguration"/>
- </
- <!-- 定義事務管理器(宣告式的事務) -->
- <beanid="transactionManager"
- class="org.springframework.orm.hibernate3.HibernateTransactionManager">
- <propertyname="sessionFactory"ref="sessionFactory"/>
- </bean>
- <!-- 配置DAO -->
- <beanid="userDaoTarget"class="com.bluesky.spring.dao.UserDaoImpl">
- <propertyname="sessionFactory"ref="sessionFactory"/>
- </bean>
- <beanid="userDao"
- class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
- <!-- 配置事務管理器 -->
- <propertyname="transactionManager"ref="transactionManager"/>
- <propertyname="target"ref="userDaoTarget"/>
- <propertyname="proxyInterfaces"value="com.bluesky.spring.dao.GeneratorDao"/>
- <!-- 配置事務屬性 -->
- <propertyname="transactionAttributes">
- <props>
- <propkey="*">PROPAGATION_REQUIRED</prop>
- </props>
- </property>
- </bean>
- </beans>
第二種方式:所有Bean共享一個代理基類
- <beanid="sessionFactory"
- class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
- <propertyname="configLocation"value="classpath:hibernate.cfg.xml"/>
- <propertyname="configurationClass"value="org.hibernate.cfg.AnnotationConfiguration"/>
- </bean>
- <!-- 定義事務管理器(宣告式的事務) -->
- <beanid="transactionManager"
- class="org.springframework.orm.hibernate3.HibernateTransactionManager">
- <propertyname="sessionFactory"ref="sessionFactory"/>
- </bean>
- <beanid="transactionBase"
- class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"
- lazy-init="true"abstract="true">
- <!-- 配置事務管理器 -->
- <propertyname="transactionManager"ref="transactionManager"/>
- <!-- 配置事務屬性 -->
- <propertyname="transactionAttributes">
- <props>
- <propkey="*">PROPAGATION_REQUIRED</prop>
- </props>
- </property>
- </bean>
- <!-- 配置DAO -->
- <beanid="userDaoTarget"class="com.bluesky.spring.dao.UserDaoImpl">
- <propertyname="sessionFactory"ref="sessionFactory"/>
- </bean>
- <beanid="userDao"parent="transactionBase">
- <propertyname="target"ref="userDaoTarget"/>
- </bean>
- </beans>
第三種方式:使用攔截器
- <beanid="sessionFactory"
- class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
- <propertyname="configLocation"value="classpath:hibernate.cfg.xml"/>
- <propertyname="configurationClass"value="org.hibernate.cfg.AnnotationConfiguration"/>
- </bean>
- <!-- 定義事務管理器(宣告式的事務) -->
- <beanid="transactionManager"
- class="org.springframework.orm.hibernate3.HibernateTransactionManager">
- <propertyname="sessionFactory"ref="sessionFactory"/>
- </bean>
- <beanid="transactionInterceptor"
- class="org.springframework.transaction.interceptor.TransactionInterceptor">
- <propertyname="transactionManager"ref="transactionManager"/>
- <!-- 配置事務屬性 -->
- <propertyname="transactionAttributes">
- <props>
- <propkey="*">PROPAGATION_REQUIRED</prop>
- </props>
- </property>
- </bean>
- <beanclass="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
- <propertyname="beanNames">
- <list>
- <value>*Dao</value>
- </list>
- </property>
- <propertyname="interceptorNames">
- <list>
- <value>transactionInterceptor</value>
- </list>
- </property>
- </bean>
- <!-- 配置DAO -->
- <beanid="userDao"class="com.bluesky.spring.dao.UserDaoImpl">
- <propertyname="sessionFactory"ref="sessionFactory"/>
- </bean>
- </beans>
第四種方式:使用tx標籤配置的攔截器
- <beanid="sessionFactory"
- class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
- <propertyname="configLocation"value="classpath:hibernate.cfg.xml"/>
- <propertyname="configurationClass"value="org.hibernate.cfg.AnnotationConfiguration"/>
- </bean>
- <!-- 定義事務管理器(宣告式的事務) -->
- <beanid="transactionManager"
- class="org.springframework.orm.hibernate3.HibernateTransactionManager">
- <propertyname="sessionFactory"ref="sessionFactory"/>
- </bean>
- <tx:adviceid="txAdvice"transaction-manager="transactionManager">
- <tx:attributes>
- <tx:methodname="*"propagation="REQUIRED"/>
- </tx:attributes>
- </tx:advice>
- <aop:config>
- <aop:pointcutid="interceptorPointCuts"
- expression="execution(* com.bluesky.spring.dao.*.*(..))"/>
- <aop:advisoradvice-ref="txAdvice"
- pointcut-ref="interceptorPointCuts"/>
- </aop:config>
- </beans>
第五種方式:全注
- <tx:annotation-driventransaction-manager="transactionManager"/>
- <beanid="sessionFactory"
- class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
- <propertyname="configLocation"value="classpath:hibernate.cfg.xml"/>
- <propertyname="configurationClass"value="org.hibernate.cfg.AnnotationConfiguration"/>
- </bean>
- <!-- 定義事務管理器(宣告式的事務) -->
- <beanid="transactionManager"
- class="org.springframework.orm.hibernate3.HibernateTransactionManager">
- <propertyname="sessionFactory"ref="sessionFactory"/>
- </bean>
- </beans>
此時在Service類上需加上@Transactional註解