Spring 事務(wù)管理三種實現(xiàn)方式詳解
一、前言
在上一篇博客中,我們學(xué)習了 Spring JdbcTemplate 實現(xiàn)轉(zhuǎn)賬操作。但是:如果轉(zhuǎn)賬過程中程序報錯,錢會只扣不加,造成數(shù)據(jù)錯誤!
所以必須使用 Spring 事務(wù)管理,保證轉(zhuǎn)賬要么全部成功,要么全部失敗。本文講解 Spring 事務(wù) 3 種配置方式,基于轉(zhuǎn)賬案例,通俗易懂,適合新手學(xué)習。
二、事務(wù)核心 API
Spring 事務(wù)管理的核心接口:
- PlatformTransactionManager:平臺事務(wù)管理器
- DataSourceTransactionManager:JDBC / MyBatis 專用實現(xiàn)類
- TransactionDefinition:事務(wù)定義(隔離級別、傳播行為)
三、環(huán)境說明
Maven 依賴(pom.xml)
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.qcby</groupId>
<artifactId>spring-aop-demo</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<!-- Spring核心 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.31</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.3.31</version>
</dependency>
<!-- 注解支持 -->
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
<version>1.3.2</version>
</dependency>
<!-- 日志 -->
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.12</version>
</dependency>
<!-- 測試 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.3.31</version>
<scope>test</scope>
</dependency>
<!-- 數(shù)據(jù)庫 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.10</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.28</version>
</dependency>
<!-- AOP 相關(guān) -->
<dependency>
<groupId>aopalliance</groupId>
<artifactId>aopalliance</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>5.3.31</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.3</version>
</dependency>
</dependencies>
</project>配置文件:application.properties 存放數(shù)據(jù)庫連接信息
jdbc.driverClassName=com.mysql.cj.jdbc.Driver jdbc.url=jdbc:mysql:///spring_db?useSSL=false&serverTimezone=UTC jdbc.username=root jdbc.password=123456
數(shù)據(jù)庫表結(jié)構(gòu)
CREATE TABLE account(
name VARCHAR(20),
money DOUBLE
);
-- 初始化數(shù)據(jù)
INSERT INTO account VALUES ('熊大',1000),('熊二',500);四、? 方式一:XML 聲明式事務(wù)
1、原理
基于 AOP 切面,在 XML 中配置事務(wù)規(guī)則,對業(yè)務(wù)方法進行增強。
2、完整 XML 配置
<?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:aop="http://www.springframework.org/schema/aop"
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/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<!-- 加載配置 -->
<context:property-placeholder location="classpath:application.properties"/>
<!-- 連接池 -->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<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>
<!-- 1. 事務(wù)管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- 2. 事務(wù)通知 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="pay" isolation="DEFAULT" propagation="REQUIRED"/>
<tx:method name="find*" read-only="true"/>
</tx:attributes>
</tx:advice>
<!-- 3. AOP 切面配置 -->
<aop:config>
<aop:advisor advice-ref="txAdvice" pointcut="execution(* com.qcby.demo4.AccountServiceImpl.pay(..))"/>
</aop:config>
<!-- Dao & Service -->
<bean id="accountDao" class="com.qcby.demo4.AccountDaoImpl">
<property name="dataSource" ref="dataSource"/>
</bean>
<bean id="accountService" class="com.qcby.demo4.AccountServiceImpl">
<property name="accountDao" ref="accountDao"/>
</bean>
</beans>3、業(yè)務(wù)代碼
// Service
public class AccountServiceImpl implements AccountService {
private AccountDao accountDao;
public void setAccountDao(AccountDao accountDao) {
this.accountDao = accountDao;
}
@Override
public void pay(String out, String in, double money) {
accountDao.outMoney(out, money);
// int i = 1 / 0; 開啟異常,事務(wù)回滾
accountDao.inMoney(in, money);
}
}五、? 方式二:XML + 注解事務(wù)
1、步驟
- 開啟注解掃描
- 開啟事務(wù)注解驅(qū)動
- 在 Service 上加
@Transactional
2、XML 配置
<?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">
<!-- 注解掃描 -->
<context:component-scan base-package="com.qcby.demo5"/>
<context:property-placeholder location="classpath:application.properties"/>
<!-- 連接池 -->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<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>
<!-- 事務(wù)管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- JdbcTemplate -->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- 開啟事務(wù)注解 -->
<tx:annotation-driven transaction-manager="transactionManager"/>
</beans>3、Service 事務(wù)注解
@Service
@Transactional(isolation = Isolation.DEFAULT)
public class AccountServiceImpl implements AccountService {
@Autowired
private AccountDao accountDao;
@Override
public void pay(String out, String in, double money) {
accountDao.outMoney(out, money);
// int a = 1/0; 報錯自動回滾
accountDao.inMoney(in, money);
}
}六、? 方式三:純注解事務(wù)(完全無 XML)
1、配置類
@Configuration
@ComponentScan("com.qcby.demo6")
@EnableTransactionManagement // 開啟事務(wù)
public class SpringConfig {
@Bean
public DataSource dataSource(){
DruidDataSource ds = new DruidDataSource();
ds.setDriverClassName("com.mysql.cj.jdbc.Driver");
ds.setUrl("jdbc:mysql:///spring_db?useSSL=false&serverTimezone=UTC");
ds.setUsername("root");
ds.setPassword("Zhen@777");
return ds;
}
@Bean
public JdbcTemplate jdbcTemplate(DataSource dataSource){
return new JdbcTemplate(dataSource);
}
@Bean
public PlatformTransactionManager transactionManager(DataSource dataSource){
return new DataSourceTransactionManager(dataSource);
}
}2、Service 代碼
@Service
@Transactional
public class AccountServiceImpl implements AccountService {
@Autowired
private AccountDao accountDao;
@Override
public void pay(String out, String in, double money) {
accountDao.outMoney(out, money);
accountDao.inMoney(in, money);
}
}七、測試代碼(通用)
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext_tx.xml")
public class Demo4Test {
@Autowired
private AccountService accountService;
@Test
public void testPay(){
accountService.pay("熊大","熊二",100);
System.out.println("? 轉(zhuǎn)賬成功(事務(wù)已生效)");
}
}八、事務(wù)三種方式
| 方式 | 優(yōu)點 |
|---|---|
| XML 聲明式事務(wù) | 無侵入、不修改代碼 |
| XML + 注解事務(wù) | 簡單易用、最常用 |
| 純注解事務(wù) | 無配置文件、簡潔 |
到此這篇關(guān)于Spring 事務(wù)管理三種實現(xiàn)方式詳解的文章就介紹到這了,更多相關(guān)Spring 事務(wù)管理內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Java?Spring事務(wù)管理超詳細指南
- Spring事務(wù)管理中@Transactional失效的8個常見場景與解決方案
- SpringBoot中TransactionTemplate事務(wù)管理的實現(xiàn)
- Spring中的事務(wù)管理及實現(xiàn)方式解析
- Mybatis事務(wù)如何跟Spring結(jié)合(數(shù)據(jù)庫事務(wù)特性和Spring事務(wù)管理源碼)
- Spring?JDBC使用步驟和事務(wù)管理
- 詳解Spring整合mybatis--Spring中的事務(wù)管理(xml形式)
- SpringBoot使用JTA實現(xiàn)對多數(shù)據(jù)源的事務(wù)管理
相關(guān)文章
更簡單更高效的Mybatis?Plus最新代碼生成器AutoGenerator
這篇文章主要為大家介紹了更簡單更高效的Mybatis?Plus最新代碼生成器AutoGenerator使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-02-02
Mybatis的SqlRunner執(zhí)行流程實現(xiàn)
MyBatis提供了一個用于操作數(shù)據(jù)庫的SqlRunner工具類,對JDBC做了很好的封裝,本文主要介紹了Mybatis的SqlRunner執(zhí)行流程實現(xiàn),具有一定的參考價值,感興趣的可以了解一下2023-10-10
Shiro整合Springboot和redis,jwt過程中的錯誤shiroFilterChainDefinition問
這篇文章主要介紹了Shiro整合Springboot和redis,jwt過程中的錯誤shiroFilterChainDefinition問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-04-04
解決zuulGateway網(wǎng)關(guān)添加路由異常熔斷問題
這篇文章主要介紹了解決zuulGateway網(wǎng)關(guān)添加路由異常熔斷問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-10-10
Spring Boot中的JdbcTemplate是什么及用法小結(jié)
Spring Boot中的JdbcTemplate是一個強大的數(shù)據(jù)庫訪問工具,它簡化了數(shù)據(jù)庫操作的過程,在本文中,我們了解了JdbcTemplate的基本概念,并演示了如何在Spring Boot應(yīng)用程序中使用它,感興趣的朋友跟隨小編一起看看吧2023-10-10
java實現(xiàn)合并2個文件中的內(nèi)容到新文件中
這篇文章主要介紹了java實現(xiàn)合并2個文件中的內(nèi)容到新文件中,思路非常不錯,這里推薦給大家。2015-03-03
解決Elasticsearch因jdk版本問題啟動失敗的問題
這篇文章主要介紹了解決Elasticsearch因jdk版本問題啟動失敗的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-07-07
SpringBoot集成P6spy實現(xiàn)自定義SQL日志打印
本文主要介紹了SpringBoot集成P6spy實現(xiàn)自定義SQL日志打印,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習或者工作具有一定的參考學(xué)習價值,需要的朋友們下面隨著小編來一起學(xué)習學(xué)習吧2023-07-07

