首页 > 其他分享 >Spring 如何实现事务管理

Spring 如何实现事务管理

时间:2023-02-07 14:02:50浏览次数:43  
标签:事务管理 事务 http Spring www 如何 org 方法

事务管理方式

在 Spring 项目中,我们可以用通过四种方式实现事务管理,分别是 编程式事务管理、基于 TransactionProxyFactoryBean的声明式事务管理、基于 @Transactional 的声明式事务管理 和 基于Aspectj AOP配置事务。其实现方式如下:

编程式事务管理


// JDBC 事务管理
Connection connection = DriverManager.getConnection("connUrl", "username", "password");
//关闭自动提交,此句代码会自动开启事务。默认为true,自动提交。
connection.setAutoCommit(false);

String sql1 = "insert into user(name) values (?)";
PreparedStatement preparedStatement1 = connection.prepareStatement(sql1);
preparedStatement1.setString(1,"Java面典");
preparedStatement1.executeUpdate();

String sql2 = "update user set name=? where id=?";
PreparedStatement preparedStatement2 = connection.prepareStatement(sql2);
preparedStatement2.setString(1, "Java面典 new");
preparedStatement2.setInt(2, 10);
preparedStatement2.executeUpdate();

try{
//提交事务
connection.commit();
}catch (SQLException e){
//失败就回滚
connection.rollback();
} finally {
preparedStatement1.close();
preparedStatement2.close();
connection.close();
}

基于 TransactionProxyFactoryBean的声明式事务管理


<?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.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">

<tx:annotation-driven transaction-manager="transactionManager"/>
</beans>

基于 @Transactional 的声明式事务管理

Spring 如何实现事务管理_spring

@Service
public class UserServiceImpl implements IUserService {

@Transactional(transactionManager = "transactionManager", rollbackFor = Exception.class)
@Override
public void add(User user) {
// todo
}
}

基于Aspectj AOP配置事务


<!-- 事务管理器 -->
<bean id="tracnsactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>

<tx:advice id="txAdvice" transaction-manager="myTracnsactionManager">
<tx:attributes>
<!-- 为连接点指定事务属性 -->
<tx:method name="add*" isolation="DEFAULT" propagation="REQUIRED"/>
<tx:method name="stockChange" isolation="DEFAULT" propagation="REQUIRED" rollback-for="StockException"/>
</tx:attributes>
</tx:advice>

<aop:config>
<!-- 切入点配置 -->
<aop:pointcut expression="execution(* *..service.*.*(..))" id="point"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="point"/>
</aop:config>

事务传播机制

Spring 的事务传播分为以下几个机制:

  • REQUIRED:如果有事务则加入事务,如果没有事务,则创建一个新的(默认值);
  • NOT_SUPPORTED:Spring 不为当前方法开启事务,相当于没有事务;
  • REQUIRES_NEW:不管是否存在事务,都创建一个新的事务,原来的方法挂起,新的方法执行完毕后,继续执行老的事务;
  • MANDATORY:必须在一个已有的事务中执行,否则报错;
  • NEVER:必须在一个没有的事务中执行,否则报错;
  • SUPPORTS:如果其他 bean 调用这个方法时,其他 bean 声明了事务,则就用这个事务,如果没有声明事务,那就不用事务;
    SUPPORTS类型的事务传播机制,是否使用事务取决于调用方法是否有事务,如果有则直接用,如果没有则不使用事务。
  • NESTED:如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与 REQUIRED 类似的操作;

注意事项

在 A 方法内,调用 B 方法时,存在以下规则:

  1. REQUIRED
    当两个方法的传播机制都是 REQUIRED 时,如果一旦发生回滚,两个方法都会回滚;
  2. REQUIRES_NEW
    当 A 方法传播机制为 REQUIRES_NEW ,会开启一个新的事务,并单独提交方法,所以 B 方法的回滚并不影响 A 方法事务提交;
  3. NESTED
    当 A 方法为 REQUIRED,B 方法为 NESTED 时,A 方法开启一个嵌套事务;
    当 A 方法回滚时,B 方法也会回滚;反之,如果 B 方法回滚,则并不影响 A 方法的提交。

事务隔离级别

TransactionDefinition 接口中定义了五个表示隔离级别的常量:

  • ISOLATION_DEFAULT:使用后端数据库默认的隔离界别,MySQL默认采用的REPEATABLE_READ 隔离级别,Oracle 默认采用的 READ_COMMITTED 隔离级别;
  • ISOLATION_READ_UNCOMMITTED:最低的隔离级别,允许读取,允许读取尚未提交的的数据变更,可能会导致脏读、幻读或不可重复读;
  • ISOLATION_READ_COMMITTED:允许读取并发事务已经提交的数据,可以阻止脏读,但是幻读或不可重复读仍有可能发生;
  • ISOLATION_REPEATABLE_READ:对同一字段的多次读取结果都是一致的,除非数据是被本身事务自己所修改,可以阻止脏读和不可重复读,但幻读仍有可能发生;
  • ISOLATION_SERIALIZABLE:最高的隔离级别,完全服从 ACID 的隔离级别。所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰,也就说,该级别可以阻止脏读、不可重复读以及幻读。但是这将严重影响程序的性能。通常情况下也不会用到该级别。

标签:事务管理,事务,http,Spring,www,如何,org,方法
From: https://blog.51cto.com/u_13146445/6042054

相关文章

  • 如何去阅读源码,我总结了18条心法
    大家好,我是三友~~这篇文章我准备来聊一聊如何去阅读开源项目的源码。在聊如何去阅读源码之前,先来简单说一下为什么要去阅读源码,大致可分为以下几点原因:最直接的原因,就......
  • Containerd 的 Bug 导致容器被重建!如何避免?
    作者简介邓宇星,SUSERancher中国区软件架构师,6年云原生领域经验,参与Rancher1.x到Rancher2.x版本迭代,目前负责RancherForopenEuler(RFO) 项目开发。最近我们关注......
  • 手机扫码登录电脑QQ出现无法登录问题该如何解决
    用QQ手机版扫描二维码安全登录电脑QQ,然后出现”当前版本过低,请升级到最新版本,报错代码[00020],为此腾讯QQ每隔一段时间会进行一次升级,但是腾讯的升级用户体验不太友好,很多......
  • MySQL 如何实现数据插入
    使用MySQL插入数据时,可以根据需求场景选择合适的插入语句,例如当数据重复时如何插入数据,如何从另一个表导入数据,如何批量插入数据等场景。本文通过给出每个使用场景下的实例......
  • 如何在SQL Server 2017中实现图形数据库
    所谓图形数据库并不是存储图片的数据库,而是基于“图论”的对象与关系。只有两种类型的表(点和线)节点表:节点表定义图模型中的实体。边缘表:边缘表定义节点表实体之间的连接查......
  • 如何使用 Terraform 在亚马逊云科技上创建 ShardingSphere Proxy 高可用集群?
    背景介绍TerraformTerraform[1]是一个Hashicorp[2]开源的基础设施自动化编排工具,使用IaC的理念来管理基础设施的变更,并得到了亚马逊云科技,GCP,AZURE等公有云厂商的......
  • pytest学习和使用8-fixture如何实现teardown功能?(yield的使用)
    (8-fixture如何实现teardown功能?(yield的使用))1引入之前学习fixture的时候,其实这个功能就类似用例的前置,给用例执行前设置一些条件;那fixture也就相当于setup的功能;那有......
  • 如何让iframe铺满整个屏幕 , iframe 高度自适应
     试了一圈方法都不好使,结果最后用的就是它本身的width和height属性啊1、定义一个父div铺满屏幕2、定义iframe的width和height为100%<!DOCTYPEhtml><htm......
  • Spring框架
    Spring框架两大核心机制(ioc(控制反转)/DI(依赖注入),和AOP(面向切面编程))Spring是一个企业级开发框架,是软件设计层面的框架,优势在于可以将应用程序进行分层,提供各个层面的......
  • 看我是如何用C#编写一个小于8KB的贪吃蛇游戏的
    译者注:这是MichalStrehovský大佬的一篇文章,他目前在微软.NETRuntime团队工作,主要是负责.NETNativeAOT功能的开发。我在前几天看到这篇文章,非常喜欢,虽然它的内容稍微......