spring聲明式事務(wù)解析
一、spring聲明式事務(wù)
1.1 spring的事務(wù)管理器
spring沒有直接管理事務(wù),而是將管理事務(wù)的責(zé)任委托給JTA或相應(yīng)的持久性機(jī)制所提供的某個(gè)特定平臺(tái)的事務(wù)實(shí)現(xiàn)。spring容器負(fù)責(zé)事物的操作,spring容器充當(dāng)切面,事務(wù)的方法稱為增強(qiáng)處理,生成的代理對(duì)象的方法就是目標(biāo)方法+增強(qiáng)也就是crud+事務(wù)程序員只用做crud的操作,也就是目標(biāo)方法和聲明哪些方法應(yīng)該在事務(wù)中運(yùn)行。
Spring提供了許多內(nèi)置事務(wù)管理器實(shí)現(xiàn):
DataSourceTransactionManager:位于org.springframework.jdbc.datasource包中,數(shù)據(jù)源事務(wù)管理器,提供對(duì)單個(gè)javax.sql.DataSource事務(wù)管理,用于Spring JDBC抽象框架、iBATIS或MyBatis框架的事務(wù)管理;
JdoTransactionManager:位于org.springframework.orm.jdo包中,提供對(duì)單個(gè)javax.jdo.PersistenceManagerFactory事務(wù)管理,用于集成JDO框架時(shí)的事務(wù)管理;
JpaTransactionManager:位于org.springframework.orm.jpa包中,提供對(duì)單個(gè)javax.persistence.EntityManagerFactory事務(wù)支持,用于集成JPA實(shí)現(xiàn)框架時(shí)的事務(wù)管理;
HibernateTransactionManager:位于org.springframework.orm.hibernate3包中,提供對(duì)單個(gè)org.hibernate.SessionFactory事務(wù)支持,用于集成Hibernate框架時(shí)的事務(wù)管理;該事務(wù)管理器只支持Hibernate3+版本,且Spring3.0+版本只支持Hibernate 3.2+版本;
JtaTransactionManager:位于org.springframework.transaction.jta包中,提供對(duì)分布式事務(wù)管理的支持,并將事務(wù)管理委托給Java EE應(yīng)用服務(wù)器事務(wù)管理器;
OC4JjtaTransactionManager:位于org.springframework.transaction.jta包中,Spring提供的對(duì)OC4J10.1.3+應(yīng)用服務(wù)器事務(wù)管理器的適配器,此適配器用于對(duì)應(yīng)用服務(wù)器提供的高級(jí)事務(wù)的支持;
WebSphereUowTransactionManager:位于org.springframework.transaction.jta包中,Spring提供的對(duì)WebSphere 6.0+應(yīng)用服務(wù)器事務(wù)管理器的適配器,此適配器用于對(duì)應(yīng)用服務(wù)器提供的高級(jí)事務(wù)的支持;
WebLogicJtaTransactionManager:位于org.springframework.transaction.jta包中,Spring提供的對(duì)WebLogic 8.1+應(yīng)用服務(wù)器事務(wù)管理器的適配器,此適配器用于對(duì)應(yīng)用服務(wù)器提供的高級(jí)事務(wù)的支持。
Spring不僅提供這些事務(wù)管理器,還提供對(duì)如JMS事務(wù)管理的管理器等,Spring提供一致的事務(wù)抽象如圖所示
spring與hibernate
說明:
spring在調(diào)用具體的事務(wù)管理器之前做了一些準(zhǔn)備工作,提前設(shè)置事務(wù)的讀寫策略,而這些事務(wù)策略是公共的東西,是寫在spring的配置文件中的,這些內(nèi)容的處理需要放在抽象類中去做
二、spring與hibernate整合中的事務(wù)處理
1.2 以xml形式
引入properties配置文件
<property name="locations"> <value>classpath:jdbc.properties</value> </property>
配置dbcp數(shù)據(jù)源
<bean id="dataSource" destroy-method="close" class="org.apache.commons.dbcp.BasicDataSource"> <property name="driverClassName" value="${jdbc.driverClassName}" /> <property name="url" value="${jdbc.url}" /> <property name="username" value="${jdbc.username}" /> <property name="password" value="${jdbc.password}" /> </bean>
引入sessionfactory,使用hibernate外部配置文件
<bean id="sessionFactory2" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"> <property name="configLocation"> <value>classpath:hibernate.cfg.xml</value> </property> </bean>
注入dao和service層
<bean id="personDao" class="cn.qjc.hibernate.dao.impl.PersonDaoImpl"> <property name="sessionFactory"> <ref bean="sessionFactory2"/> </property> </bean> <bean id="personService" class="cn.qjc.hibernate.service.impl.PersonServiceImpl"> <property name="personDao"> <ref bean="personDao"/> </property> </bean>
配置hibernate事務(wù)管理器
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> <property name="sessionFactory"> <ref bean="sessionFactory2"/> </property> </bean>
配置聲明式事務(wù)
作用:
1、告訴spring容器事務(wù)管理器
2、告訴spring容器什么樣的方法使用什么樣的事務(wù)
<tx:advice transaction-manager="transactionManager" id="tx"> <tx:attributes> <!-- name 目標(biāo)方法的范圍 islation 隔離級(jí)別 propagation 傳播屬性 read-only true 只讀事務(wù) false 讀寫事務(wù) --> <tx:method name="save*" isolation="DEFAULT" propagation="REQUIRED" read-only="false"/> </tx:attributes> </tx:advice>
配置切入點(diǎn)
<aop:config> <aop:pointcut expression="execution(* cn.qjc.hibernate.service.impl.*.*(..))" id="perform"/> <span style="white-space:pre"> </span><!-- 將切入點(diǎn)應(yīng)用到增強(qiáng)方法 --> <aop:advisor advice-ref="tx" pointcut-ref="perform"/> </aop:config>
dao實(shí)現(xiàn)類
* 實(shí)現(xiàn)方法一:繼承HibernateDaoSupport * @author qjc */ public class PersonDaoImpl extends HibernateDaoSupport implements PersonDao{ @Override public void savePerson(Person person) { this.getHibernateTemplate().save(person); } }
測(cè)試
...
注意:
1、如果一個(gè)DAO類繼承了HibernateDaoSupport,只需要在spring配置文件中注入SessionFactory就可以了。
2、如果一個(gè)DAO類沒有繼承HibernateDaoSupport,需要有一個(gè)SessionFactory的屬性,并且在配置文件中進(jìn)行注入。
<bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate"> <property name="sessionFactory" ref="sessionFactory2"></property> </bean>
1.2 以注解形式
1、在配置文件中應(yīng)用spring的自動(dòng)掃描機(jī)制
<context:component-scan base-package="cn.qjc"/>
2、在配置文件中引入注解解析器
<tx:annotation-driven transaction-manager="transactionManager"/>
3、在service層通過@Transaction進(jìn)行注解
注意:如果在類級(jí)別上被注解為只讀事務(wù),但是這個(gè)類中的方法中@Transaction注解的事務(wù)設(shè)置將優(yōu)先于類級(jí)別注解的事務(wù)設(shè)置。
1.3 spring事務(wù)的傳播屬性
required: 業(yè)務(wù)方法需要在一個(gè)事務(wù)中運(yùn)行。如果方法運(yùn)行時(shí),已經(jīng)處在一個(gè)事務(wù)中,那么加入到該事務(wù),否則為自己創(chuàng)建一個(gè)新事務(wù)(默認(rèn))
not-supported:spring容器不開啟事務(wù),如果方法在一個(gè)事務(wù)中被調(diào)用,該事務(wù)會(huì)被掛起,該方法結(jié)束后,事務(wù)恢復(fù)
requiresnew:不管是否存在事務(wù),業(yè)務(wù)方法總會(huì)創(chuàng)建一個(gè)新事務(wù)。
mandatorky: 業(yè)務(wù)方法只能在一個(gè)已經(jīng)存在的事務(wù)中執(zhí)行,如果業(yè)務(wù)方法在沒有事務(wù)下調(diào)用,容器拋出例外。
此外還有supports、never、nested等屬性,但是通常使用默認(rèn)
propagation="required" 此配置可以解決事務(wù)嵌套問題,何為事務(wù)嵌套?
比如:
在工作流框架和操作service層的某個(gè)方法中都存在事務(wù),service層也有自己的事務(wù),當(dāng)service執(zhí)行的時(shí)候,就會(huì)出現(xiàn)事務(wù)嵌套,即方法本身有事務(wù),方法中的方法還有事務(wù),這就是事務(wù)嵌套。而spring通過事務(wù)傳播屬性propagation="required"解決了這一問題。
1.4 OpenInSessionView
在s2sh整合以后,spring管理事務(wù),由于使用的是spring的聲明式事務(wù)處理方式,所以在調(diào)用this.getHibernateTemplate()這個(gè)方法執(zhí)行完之后,session立即關(guān)閉,如果當(dāng)前執(zhí)行的方法有事務(wù),當(dāng)事務(wù)環(huán)境的方法被調(diào)用完畢后session關(guān)閉。所以當(dāng)值在頁面輸出時(shí)會(huì)產(chǎn)生異常。
處理方式為:OpenSessionInview模式(web.xml中配置)
<filter> <filter-name>hibernateFilter</filter-name> <filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class> <!-- singleSession默認(rèn)為true,若設(shè)置為false則等于沒有OpenSessionInView --> <init-param> <param-name>singleSession</param-name> <param-value>true</param-value> </init-param> </filter> <filter-mapping> <filter-name>hibernateFilter</filter-name> <url-pattern>/PersonService</url-pattern> </filter-mapping>
從上面代碼可以看出,當(dāng)提交一個(gè)請(qǐng)求時(shí),OpenSessionInView中已經(jīng)把session開啟了,在response以后才要關(guān)閉session,也就意味著有了openSessionInView必須在struts2的過濾器之前。(放struts2過濾器位置上面)
但是開啟OpenSessionInView也有缺點(diǎn):因?yàn)閟ession關(guān)閉被延后了,而hibernate的一級(jí)緩存在session中,所以會(huì)導(dǎo)致大量的緩存中的數(shù)據(jù)被長(zhǎng)時(shí)間停留在內(nèi)存中。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- Spring的編程式事務(wù)和聲明式事務(wù)詳解
- Spring聲明式事務(wù)和@Aspect的攔截順序問題的解決
- spring聲明式事務(wù)管理解析
- Spring編程式和聲明式事務(wù)實(shí)例講解小結(jié)
- spring 聲明式事務(wù)實(shí)現(xiàn)過程解析
- Spring實(shí)戰(zhàn)之使用TransactionProxyFactoryBean實(shí)現(xiàn)聲明式事務(wù)操作示例
- Spring實(shí)戰(zhàn)之使用注解實(shí)現(xiàn)聲明式事務(wù)操作示例
- 詳解Spring學(xué)習(xí)之聲明式事務(wù)管理
- 關(guān)于Spring中聲明式事務(wù)的使用詳解
相關(guān)文章
Java虛擬機(jī)JVM之server模式與client模式的區(qū)別
這篇文章主要介紹了Java虛擬機(jī)JVM的client模式和Server模式兩者的區(qū)別和聯(lián)系2017-12-12SpringCloud實(shí)戰(zhàn)小貼士之Zuul的路徑匹配
這篇文章主要介紹了SpringCloud實(shí)戰(zhàn)小貼士之Zuul的路徑匹配,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-10-10SpringBoot詳細(xì)講解異步任務(wù)如何獲取HttpServletRequest
在使用框架日常開發(fā)中需要在controller中進(jìn)行一些異步操作減少請(qǐng)求時(shí)間,但是發(fā)現(xiàn)在使用@Anysc注解后會(huì)出現(xiàn)Request對(duì)象無法獲取的情況,本文就此情況給出完整的解決方案2022-04-04SpringBoot如何實(shí)現(xiàn)starter原理詳解
這篇文章主要介紹了SpringBoot如何實(shí)現(xiàn)starter原理詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-06-06Spring中的@ControllerAdvice和ResponseBodyAdvice詳解
這篇文章主要介紹了Spring中的@ControllerAdvice和ResponseBodyAdvice詳解,@ControllerAdvice作用于@Controller修飾的類里面的所有方法,ResponseBodyAdvice作用于@ResponseBody注解修飾的方法,它可以對(duì)這些方法的返回值進(jìn)行修改,需要的朋友可以參考下2024-01-01springboot項(xiàng)目攔截前端請(qǐng)求中的特殊字符串(解決方案)
springboot項(xiàng)目中,需要對(duì)前端請(qǐng)求數(shù)據(jù)進(jìn)行過濾,攔截特殊字符,本文通過實(shí)例代碼給大家分享完美解決方案,感興趣的朋友一起看看吧2023-10-10