1、Spring 事务控制方式
-
Spring 的事务控制可以分为编程式事务控制和声明式事务控制。
-
编程式,即编写有关事务的代码,与业务代码耦合,不常用。
-
声明式,采用配置或注解的方式实现事务,与业务代码解耦,常用。
2、编程式事务控制
2.1、相关概念
-
org.springframework.transaction.PlatformTransactionManager
接口,是 Spring 提供的事务管理器接口,Spring 中所提供的事务管理器基本上都需实现该接口。 -
当 DAO 层所使用的技术、框架不同时,使用的事务管理器实现类也不同:
-
org.springframework.transaction.PlatformTransactionManager
接口中的方法:
package org.springframework.transaction;
import org.springframework.lang.Nullable;
public interface PlatformTransactionManager extends TransactionManager {
TransactionStatus getTransaction(@Nullable TransactionDefinition var1) throws TransactionException;
void commit(TransactionStatus var1) throws TransactionException;
void rollback(TransactionStatus var1) throws TransactionException;
}
org.springframework.transaction.TransactionDefinition
-
org.springframework.transaction.TransactionStatus
:
2.2、举例
spring-40 spring-413、声明式事务控制
-
声明式的本质是使用 AOP 实现
-
声明式事务控制明确事项:
核心业务代码
事务增强代码(使用 Spring 已提供事务管理器)
切面配置
3.1、XML
CREATE TABLE xxx(
id INT NOT NULL,
name VARCHAR(3) NOT NULL
);
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
@NoArgsConstructor
@AllArgsConstructor
@Data
@ToString
public class Xxx {
private Integer id;
private String name;
}
jdbc_driver = com.mysql.cj.jdbc.Driver
jdbc_url = jdbc:mysql://127.0.0.1:3306/test_1?characterEncoding=UTF-8
jdbc_username = root
jdbc_password =
<?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 https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context https://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 https://www.springframework.org/schema/aop/spring-aop.xsd">
<context:component-scan base-package="com.yscyber.spring.eight"/>
<context:property-placeholder location="classpath:jdbc.properties"/>
<!-- 数据源 -->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="${jdbc_driver}"/>
<property name="url" value="${jdbc_url}"/>
<property name="username" value="${jdbc_username}"/>
<property name="password" value="${jdbc_password}"/>
</bean>
<!-- 配置 JdbcTemplate -->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<constructor-arg name="dataSource" ref="dataSource"/>
</bean>
<!-- 配置事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- 配置增强通知(基于“事务”的增强通知) -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<!-- 所有被增强的方法(所有需要使用事务的方法)使用事务的默认配置(隔离级别、传播行为等) -->
<tx:method name="*"/>
</tx:attributes>
</tx:advice>
<aop:config>
<!-- 使用 <aop:advisor> 对某方法进行增强(某方法开启事务) -->
<aop:advisor advice-ref="txAdvice" pointcut="execution(* com.yscyber.spring.eight.repo.XxxRepo.insertXxx(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut="execution(* com.yscyber.spring.eight.repo.XxxRepo.updateXxxById(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut="execution(* com.yscyber.spring.eight.repo.XxxRepo.deleteXxxById(..))"/>
</aop:config>
</beans>
import com.yscyber.spring.eight.pojo.Xxx;
import java.util.List;
public interface XxxRepo {
List<Xxx> listAllXxx();
int insertXxx(Xxx xxx);
int updateXxxById(Integer id, Xxx xxx);
int deleteXxxById(Integer id);
}
import com.yscyber.spring.eight.pojo.Xxx;
import com.yscyber.spring.eight.repo.XxxRepo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public class XxxRepoImpl implements XxxRepo {
@Autowired
private JdbcTemplate jdbcTemplate;
@Override
public List<Xxx> listAllXxx() {
String sql = "SELECT id,name" +
" FROM xxx";
return jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(Xxx.class));
}
@Override
public int insertXxx(Xxx xxx) {
String sql = "INSERT INTO xxx(id,name)" +
" VALUES(?,?)";
return jdbcTemplate.update(sql, xxx.getId(), xxx.getName());
}
@Override
public int updateXxxById(Integer id, Xxx xxx) {
String sql = "UPDATE xxx" +
" SET id=?,name=?" +
" WHERE id=?";
return jdbcTemplate.update(sql, xxx.getId(), xxx.getName(), id);
}
@Override
public int deleteXxxById(Integer id) {
String sql = "DELETE FROM xxx" +
" WHERE id=?";
return jdbcTemplate.update(sql, id);
}
}
-
<tx:method>
:事务参数的配置
3.2、注解
<!-- 配置事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- 开启有关 Spring 事务的注解扫描 -->
<tx:annotation-driven/>
@Transactional(propagation = Propagation.REQUIRED, isolation =
Isolation.REPEATABLE_READ, timeout = -1, readOnly = false)
public void xxx() {
······
}
@Transactional
注解既可以添加在方法上,也可以添加在类上,添加在类上说明对类中的所有方法,都使用事务管理。
网友评论