当前位置: 首页 > news >正文

Spring AOP源码篇四之 数据库事务

了解了Spring AOP执行过程,再看Spring事务源码其实非常简单。
首先从简单使用开始, 演示Spring事务使用过程

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: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.xsdhttp://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsdhttp://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"><!-- 数据库连接池 --><bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" destroy-method="close"><property name="url" value="jdbc:mysql:///custom_db" /><property name="username" value="root" /><property name="password" value="123456" /><property name="driverClassName" value="com.mysql.jdbc.Driver" /></bean><!-- JdbcTemplate 对象 --><bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"><property name="dataSource" ref="dataSource"></property></bean><!-- transactionManager 对象 --><bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="dataSource"></property></bean><tx:advice id="txAdvice" transaction-manager="transactionManager"><tx:attributes><tx:method name="*" propagation="REQUIRED"/></tx:attributes></tx:advice><aop:config><aop:advisor advice-ref="txAdvice" pointcut="execution(* org.spring.tx.dao.*.*(..))"></aop:advisor></aop:config><bean id="userDao" class="org.spring.tx.dao.UserDaoImpl"><constructor-arg index="0" ref="jdbcTemplate"></constructor-arg></bean></beans>

实体类:

package org.spring.tx.dto;public class UserDto {private Long id;private String UserName;public Long getId() {return id;}public void setId(Long id) {this.id = id;}public String getUserName() {return UserName;}public void setUserName(String userName) {UserName = userName;}
}

业务Dao类:

package org.spring.tx.dao;import org.spring.tx.dto.UserDto;public interface UserDao {void insert(UserDto userDto);
}
package org.spring.tx.dao;import org.spring.tx.dto.UserDto;
import org.springframework.jdbc.core.JdbcTemplate;public class UserDaoImpl implements UserDao {//注入 JdbcTemplateprivate JdbcTemplate jdbcTemplate;public UserDaoImpl(JdbcTemplate jdbcTemplate) {this.jdbcTemplate = jdbcTemplate;}@Overridepublic void insert(UserDto userDto) {//创建 sql 语句String sql = "insert into user (username)values(?)";//调用方法实现Object[] args = {userDto.getUserName()};//返回影响行数int update = jdbcTemplate.update(sql,args);System.out.println("user新增条数:" + update);//throw new RuntimeException("业务出错了!!!");}
}

测试代码:

package org.spring.tx;import org.spring.tx.dao.UserDao;
import org.spring.tx.dto.UserDto;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class MainTest {public static void main(String[] args) {ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-tx.xml");applicationContext.start();UserDao userDao = applicationContext.getBean(UserDao.class);UserDto userDto = new UserDto();userDto.setUserName("zhangsan");userDao.insert(userDto);applicationContext.stop();}
}

执行结果:

==================从源码角度简单分析一下=====================
根据Spring AOP过程(参考:Spring AOP源码篇二之 代理工厂ProxyFactory学习-CSDN博客  Spring AOP源码篇三之 xml配置-CSDN博客),增强工作由Advice完成,而事务的Advice对应的是TransactionInterceptor.
public class TransactionInterceptor extends TransactionAspectSupport implements MethodInterceptor, Serializable {public TransactionInterceptor() {}public TransactionInterceptor(PlatformTransactionManager ptm, Properties attributes) {setTransactionManager(ptm);setTransactionAttributes(attributes);}public TransactionInterceptor(PlatformTransactionManager ptm, TransactionAttributeSource tas) {setTransactionManager(ptm);setTransactionAttributeSource(tas);}//TransactionInterceptor实现了Advice(MethodInterceptor)接口,增强工作由该方法完成//核心代码,方法调用入口public Object invoke(final MethodInvocation invocation) throws Throwable {Class<?> targetClass = (invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null);// 父类TransactionAspectSupport中方法return invokeWithinTransaction(invocation.getMethod(), targetClass, new InvocationCallback() {public Object proceedWithInvocation() throws Throwable {return invocation.proceed();}});}//---------------------------------------------------------------------// Serialization support//---------------------------------------------------------------------private void writeObject(ObjectOutputStream oos) throws IOException {// Rely on default serialization, although this class itself doesn't carry state anyway...oos.defaultWriteObject();// Deserialize superclass fields.oos.writeObject(getTransactionManagerBeanName());oos.writeObject(getTransactionManager());oos.writeObject(getTransactionAttributeSource());oos.writeObject(getBeanFactory());}private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {// Rely on default serialization, although this class itself doesn't carry state anyway...ois.defaultReadObject();// Serialize all relevant superclass fields.// Superclass can't implement Serializable because it also serves as base class// for AspectJ aspects (which are not allowed to implement Serializable)!setTransactionManagerBeanName((String) ois.readObject());setTransactionManager((PlatformTransactionManager) ois.readObject());setTransactionAttributeSource((TransactionAttributeSource) ois.readObject());setBeanFactory((BeanFactory) ois.readObject());}}

http://www.lryc.cn/news/395983.html

相关文章:

  • 小波与傅里叶变换的对比(Python)
  • Linux-sqlplus安装
  • LeetCode 算法:课程表 c++
  • 前端面试题30(闭包和作用域链的关系)
  • A股本周在3000点以下继续筑底,本周依然继续探底?
  • Javadoc介绍
  • C# Application.DoEvents()的作用
  • IDEA如何创建原生maven子模块
  • LCD EMC 辐射 测试随想
  • Docker安装遇到问题:curl: (7) Failed to connect to download.docker.com port 443: 拒绝连接
  • 阿里云安装rabbitMQ
  • 中文大模型基准测评2024上半年报告
  • 新火种AI|OpenAI的CEO又有新动作?这次他成立了AI健康公司
  • 中介子方程五十
  • 如何借助社交媒体影响者的力量,让品牌影响力倍增?
  • Python面试题:Python 中的 `property` 函数有什么用?
  • 十五、小型电脑没有数字键及insert,怎么解决IDEA快速插入getset构造这些方法
  • 【鸿蒙学习笔记】属性学习迭代笔记
  • 工具推荐:滴答清单
  • 阶段三:项目开发---大数据开发运行环境搭建:任务4:安装配置Spark集群
  • SDIO CMD 数据部分 CRC 计算规则
  • 每日一编程,早点拿offer
  • https创建证书
  • C++ 是否变得比 C 更流行了?
  • Redis-Jedis连接池\RedisTemplate\StringRedisTemplate
  • Obsidian 文档编辑器
  • Spring Boot项目中JPA操作视图会改变原表吗?
  • C++之goto陈述
  • ChatGPT提问提示指南PDF下载经典分享推荐书籍
  • 架构设计(2)云原生架构与实例部署