詳解Spring學習之聲明式事務管理
前言
在前面的小節(jié)中,我們學習了關于事務的概念以及事務管理的重要性,并且通過編程使用Spring的編程式事務管理進行操作,加深對事務管理的重要性的學習,不過,由于編程式的事務管理使用起來不是很方便,所以在日常的開發(fā)中基本不怎么使用,接下來的內容我們將學習使用Spring的聲明式事務管理,這里有一個地方需要明白的是,Spring的聲明式事務管理的實現(xiàn)方式其實是通過AOP的方式來實現(xiàn)的,也就是為原始的事務管理對象創(chuàng)建代理對象,從而實現(xiàn)事務管理增強的
基于TransactionProxyFactoryBean的事務管理配置
經(jīng)過前面的學習,可以知道,Spring中配置AOP有三種方式,分別是通過ProxyFactoryBean創(chuàng)建代理,通過XML的方式以及通過注解的方式,既然Spring事務管理是通過AOP來實現(xiàn)的,那么對應的就有三種不同的方式,首先來看下基于TransactionProxyFactoryBean的管理方式
首先是Spring的配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<!--開啟自動掃描-->
<context:component-scan base-package="cn.xuhuanfeng.transaction"/>
<!--配置數(shù)據(jù)源,這里采用dbcp-->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="url" value="jdbc:mysql://localhost:3306/spring"/>
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="username" value="root"/>
<property name="password" value="huanfeng"/>
</bean>
<!--配置JdbcTemplate-->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<!--注入數(shù)據(jù)源-->
<property name="dataSource" ref="dataSource"/>
</bean>
<!--配置事務管理-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!--注入數(shù)據(jù)源-->
<property name="dataSource" ref="dataSource"/>
</bean>
<!--為AccountService創(chuàng)建代理類-->
<bean id="accountServiceProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<!--注入事務管理-->
<property name="transactionManager" ref="transactionManager"/>
<!--注入目標類,也就是所要增強的類-->
<property name="target" ref="accountService"/>
<!--配置相應的事務屬性-->
<property name="transactionAttributes">
<props>
<!--指定不同的事務的處理方式
配置格式:事務傳播方式,隔離級別,readOnly,-Exception,+Exception
傳播行為是唯一必須配置的,其他的如果不配置則使用默認
-Exception表示如果發(fā)生對應的異常,則回滾事務
+Exception表示即使發(fā)生對應的異常,也依舊提交事務
-->
<prop key="transfer">PROPAGATION_REQUIRED,ISOLATION_DEFAULT</prop>
</props>
</property>
</bean>
</beans>
對應的持久層代碼
@Repository
public class AccountDao {
@Autowired
private JdbcTemplate jdbcTemplate;
public void transferIn(String name, double money){
String sql = "update account set money = money + ? where name = ?";
jdbcTemplate.update(sql, money, name);
}
public void transferOut(String name, double money){
String sql = "update account set money = money - ? where name = ?";
jdbcTemplate.update(sql, money, name);
}
}
業(yè)務層代碼
@Service
public class AccountService {
@Autowired
private AccountDao accountDao;
public void transfer(final String fromName,final String toName,final double money){
accountDao.transferOut(fromName, money);
int d = 1/0; // 除0異常
accountDao.transferIn(toName, money);
}
}
通過上面的配置之后,當我們在使用AccountService的時候,由于獲取的對象的代理后的對象,所以Spring會自動進行事務的監(jiān)管,而我們需要做的就是配置對應的事務傳播類型以及事務管理級別等的信息,這種方式明顯對代碼以及沒有什么侵入了,但是使用這種方式意味著沒有都需要為不同的服務對象創(chuàng)建對應的代理對象,這其實是不太方便的,接下來我們來看下使用aop/tx命名空間來進行配置的方式。
基于aop/tx命名空間的事務管理配置
由于是對上面的業(yè)務操作進行事務管理,而且經(jīng)過上一小節(jié)的學習,我們也基本熟悉了該業(yè)務,所以這里直接演示配置的代碼
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<!--
這里配置同前,故省略
-->
<!--aop配置-->
<aop:config>
<!--配置切點-->
<aop:pointcut id="serviceMethod" expression="execution(* cn.xuhuanfeng.transaction.AccountService.*(..))"/>
<!--對應的切面-->
<aop:advisor advice-ref="txAdvice" pointcut-ref="serviceMethod"/>
</aop:config>
<!--配置事務增強-->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<!--配置對應的事務管理,其中name為與事務相關的方法名,可以使用通配符-->
<tx:method name="transfer*" isolation="DEFAULT" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>
</beans>
可以看到,通過XML配置的方式,可以更加靈活地進行事務管理
基于注解的事務管理配置
基于注解的配置方式提供了更加簡單的配置方式,只需要使用@Transactional注解進行標注,并且開啟對應的掃描即可。
// 配置相應的隔離級別、事務傳播等
@Transactional(isolation = Isolation.DEFAULT, propagation = Propagation.REQUIRED)
@Service
public class AccountService {
// 省略其他內容
}
Spring配置文件也相對比較簡單了
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<!--數(shù)據(jù)源配置等同上-->
<!--通過tx命名空間,開啟主機自動掃描,并且注入事務管理器-->
<tx:annotation-driven transaction-manager="transactionManager"/>
</beans>
可以看到,通過注解配置的方式是最簡單的配置方式,在日常的開發(fā)中,這種方式的使用的頻率也比較高
總結
本小節(jié)主要學習了Spring聲明式事務管理的配置,包括了使用TransactionProxyFactoryBean、通過aop/tx命名空間的XML配置以及基于注解的配置方式,其中,基于注解的配置方式是比較簡單的,也是使用頻率比較高的一種
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關文章
監(jiān)控Spring Boot 項目運行情況操作方法
在實際開發(fā)中,經(jīng)常會遇到想要獲取到服務器應用的運行情況的場景,在微服務架構下對于每個應用運行情況的監(jiān)控是保證系統(tǒng)高可用的關鍵,本文給大家介紹如何實現(xiàn)在Spring Boot的jar包中對系統(tǒng)的運行情況進行監(jiān)控操作,感興趣的朋友跟隨小編一起看看吧2024-08-08
解決IDEA報錯,無效的源發(fā)行版 無效的目標發(fā)行版:22問題
在項目編譯過程中,可能會出現(xiàn)“無效的源發(fā)行版”或“無效的目標發(fā)行版”的報錯信息,原因通常是編譯使用的JDK版本與項目設置的發(fā)布版本不一致,解決這類問題的辦法是統(tǒng)一JDK版本,具體操作為:在IDE的項目設置中(如File->ProjectStructure->ProjectSettings)2024-10-10
解決ObjectMapper.convertValue() 遇到的一些問題
這篇文章主要介紹了解決ObjectMapper.convertValue() 遇到的一些問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-06-06
SpringBoot解決BigDecimal傳到前端后精度丟失問題
這篇文章將通過示例詳細為大家介紹SpringBoot如何解決BigDecimal傳到前端后精度丟失問題,文中的示例代碼講解詳細,感興趣的可以了解一下2022-06-06

