java事务相关知识小总结

本文介绍了Spring的声明式和编程式事务管理,详细解释了事务的传播行为、隔离级别,以及MySQL和Redis事务的使用、失效条件和MyBatis中的事务配置与控制。强调了处理事务时应注意的要点和潜在问题。
摘要由CSDN通过智能技术生成

java事务相关知识小总结

Spring 事务相关知识:

Spring提供了强大的事务管理机制,支持声明式事务和编程式事务。以下是一些与Spring事务相关的关键知识点:

声明式事务管理:

  • 使用 @Transactional 注解声明事务,可以应用在类级别或方法级别。

  • 提供了一系列的属性,如 propagation(传播行为)、isolation(隔离级别)、readOnly(只读事务)、timeout(超时设置)等。

@Service
@Transactional
public class MyService {
    // ...
}

编程式事务管理:

  • 使用 TransactionTemplatePlatformTransactionManager 进行编程式事务管理。

@Service
public class MyService {
​
    private final PlatformTransactionManager transactionManager;
​
    @Autowired
    public MyService(PlatformTransactionManager transactionManager) {
        this.transactionManager = transactionManager;
    }
​
    public void programmaticTransaction() {
        TransactionTemplate transactionTemplate = new TransactionTemplate(transactionManager);
        transactionTemplate.execute(status -> {
            // your transactional code
            return null;
        });
    }
}

事务传播行为:

Spring 提供了多种事务传播行为,常用的包括:

  • REQUIRED(默认):

    • 如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务。

  • REQUIRES_NEW:

    • 总是创建一个新的事务。如果当前存在事务,则将当前事务挂起。

  • NESTED:

    • 如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则行为类似于 REQUIRED

  • SUPPORTS:

    • 支持当前事务,如果没有当前事务,则以非事务方式执行。

  • NOT_SUPPORTED:

    • 以非事务方式执行,如果当前存在事务,则将其挂起。

  • NEVER:

    • 以非事务方式执行,如果当前存在事务,则抛出异常。

  • MANDATORY:

    • 强制要求存在一个事务,如果没有,则抛出异常。

  • NEVER:

    • 总是以非事务方式执行,如果当前存在事务,则抛出异常。

事务隔离级别:

  • DEFAULT:

    • 使用数据库默认的隔离级别。

  • READ_UNCOMMITTED:

    • 允许脏读、不可重复读、幻读。

  • READ_COMMITTED:

    • 禁止脏读,但允许不可重复读、幻读。

  • REPEATABLE_READ:

    • 禁止脏读、不可重复读,但允许幻读。

  • SERIALIZABLE:

    • 禁止脏读、不可重复读、幻读。

事务的失效条件:

事务的失效是指在一些情况下,尽管使用了事务管理机制,但事务并未按照期望的方式工作。以下是一些可能导致事务失效的常见原因:

  1. 未捕获的异常:

    • 如果在事务中的代码块中抛出未捕获的异常,并且这个异常不是继承自 RuntimeException,Spring 的事务管理机制可能无法感知到异常,从而导致事务无法回滚。

  2. 自调用问题:

    • 在同一类中,使用 this 关键字进行方法调用时,事务失效,因为默认是通过代理对象来增强事务的。

    @Service
    @Transactional
    public class MyService {
    ​
        public void outerMethod() {
            innerMethod(); // 调用自己类中的方法
        }
    ​
        public void innerMethod() {
            // ...
        }
    }

  3. 不在公共方法上使用事务注解:

    • 如果在非公共方法上使用 @Transactional 注解,事务也会失效,因为Spring AOP 默认只拦截公共方法。

    @Service
    public class MyService {
    ​
        @Transactional
        public void publicMethod() {
            // ...
        }
    ​
        @Transactional
        private void privateMethod() {
            // 不会生效
        }
    }

  4. 事务的配置问题:

    • 检查事务的配置,如传播行为、隔离级别等,确保其符合业务需求。

  5. 数据库引擎不支持事务:

    • 确保数据库引擎支持事务,以及相关表的存储引擎是否支持事务。

在使用事务时,需要仔细检查代码和配置,确保事务的正确性。阅读日志和检查异常信息有助于识别和解决事务失效的问题。

MySQL 事务的相关知识:

MySQL 是一种支持事务的关系型数据库管理系统(RDBMS)。以下是一些关于 MySQL 事务的基本知识:

事务的四个特性(ACID):

  • 原子性(Atomicity): 事务中的所有操作要么全部执行成功,要么全部失败回滚。

  • 一致性(Consistency): 事务执行后,数据库从一个一致性状态转移到另一个一致性状态。

  • 隔离性(Isolation): 多个事务同时执行时,一个事务的执行不应影响其他事务。

  • 持久性(Durability): 一旦事务提交,其结果应该在数据库中持久存在,即使系统故障。

事务的隔离级别:

  • MySQL 支持多种隔离级别,包括读未提交(READ UNCOMMITTED)、读提交(READ COMMITTED)、可重复读(REPEATABLE READ)和串行化(SERIALIZABLE)。

事务的开始和提交:

  • 使用 START TRANSACTIONBEGIN 开始事务,使用 COMMIT 提交事务。也可以使用 ROLLBACK 进行事务回滚。

START TRANSACTION;
-- or BEGIN;
-- your SQL statements
COMMIT;
-- or ROLLBACK;

事务的自动提交:

  • 默认情况下,MySQL 是自动提交事务的,每个 SQL 语句都被视为一个事务。可以使用 SET AUTOCOMMIT = 0 关闭自动提交,然后使用 COMMITROLLBACK 手动管理事务。

SET AUTOCOMMIT = 0;
-- your SQL statements
COMMIT;
-- or ROLLBACK;

MySQL 事务的失效条件:

MySQL 事务的失效条件可能包括以下情况:

  1. 隔离级别问题:

    • 在较低的隔离级别下,可能发生脏读、不可重复读或幻读。选择合适的隔离级别,根据业务需求来平衡一致性和性能。

  2. 死锁:

    • 多个事务相互等待对方释放锁,导致所有事务都无法继续执行。

  3. 锁超时:

    • 如果事务持有锁的时间过长,可能会导致其他事务因为等待超时而失败。

  4. 事务太大:

    • 如果一个事务包含大量的数据修改,可能会导致锁定太多的资源,影响其他事务的执行。

  5. 并发性问题:

    • 当大量并发事务同时访问数据库时,可能会出现性能问题,需要适当调整事务隔离级别和优化 SQL 查询。

  6. 数据库故障:

    • 数据库的故障可能导致事务无法正常提交,需要合适的异常处理和重试机制。

Redis 事务的相关知识:

在 Redis 中,事务是通过 MULTIEXECDISCARDWATCH 等命令实现的。

  1. MULTI: 开始一个事务,之后的命令都将被放入队列而不会立即执行。

  2. EXEC: 执行所有在 MULTI 开始和 EXEC 结束之间的命令。

  3. DISCARD: 取消事务,清空所有在 MULTI 开始和 DISCARD 结束之间的命令。

  4. WATCH: 监视一个或多个键,当这些键被其他客户端修改时,事务将被取消。

事务的基本使用示例:

MULTI
SET key1 "value1"
GET key1
INCR key2
EXEC

以上命令会将 SETGETINCR 三个命令作为一个事务进行处理。

Redis 事务的失效条件:

在 Redis 中,虽然有事务的概念,但 Redis 事务并不支持像关系型数据库那样的 ACID 特性。以下是一些 Redis 事务可能失效的情况:

  1. WATCH 机制的限制:

    • Redis 使用 WATCH 命令来实现乐观锁,但 WATCH 只能监视字符串类型的键,不能监视集合或哈希表。

  2. 命令执行失败:

    • 如果在 MULTI 和 EXEC 之间有命令执行失败,整个事务都不会回滚。Redis 事务并不具备回滚的能力。

  3. 命令语法错误:

    • 如果在事务中存在语法错误的命令,整个事务将中断,后续命令不会执行。

  4. 执行命令失败:

    • 如果在 EXEC 执行时,其中一个命令执行失败(比如对字符串类型执行了非字符串类型的命令),整个事务将中断。

  5. 网络问题:

    • 在 EXEC 执行之前,如果与 Redis 服务器的连接断开,事务也会中断。

  6. WATCH 的 CAS 版本冲突:

    • 如果使用 WATCH 监控了某个键,但在执行 EXEC 时发现键的 CAS 版本已经发生了变化,事务也会中断。

需要注意的是,Redis 事务并不提供回滚的能力,而是执行到出错的那一步,之后的命令不再执行。因此,在使用 Redis 事务时,需要谨慎考虑其适用场景和特性。如果需要严格的事务控制,可能需要考虑其他数据库方案。

MyBatis 事务的相关知识:

MyBatis 是一个持久层框架,它允许开发者使用简单的 XML 或注解配置来映射原生信息,将 Java 对象映射到数据库表中。MyBatis 不直接处理事务,而是依赖于底层的数据库事务。

事务配置:

  • 在 MyBatis 中,事务的管理通常交由底层的数据库连接池(如 Druid、HikariCP)来处理。MyBatis 不提供自己的事务管理器,而是通过配置数据源和使用 JDBC 事务。

<!-- MyBatis 配置文件 -->
<configuration>
    <!-- 数据源配置 -->
    <dataSource type="POOLED">
        <!-- 配置数据源相关信息 -->
    </dataSource>
</configuration>

事务控制:

  • 在 MyBatis 中,可以使用 @Transactional 注解来声明事务。这个注解可以在类级别或方法级别使用。

@Service
@Transactional
public class MyService {
    // ...
}
javaCopy code@Mapper
public interface MyMapper {
    @Transactional
    void myMethod();
}

手动提交和回滚:

  • MyBatis 默认是开启自动提交的,如果需要手动控制事务,可以在 SqlSession 中使用 commit()rollback() 方法。

SqlSession sqlSession = sqlSessionFactory.openSession();
try {
    // your code
    sqlSession.commit(); // 提交事务
} catch (Exception e) {
    sqlSession.rollback(); // 回滚事务
} finally {
    sqlSession.close();
}

MyBatis 事务的失效条件:

MyBatis 事务失效可能与底层数据库事务相关,常见的失效条件包括:

  1. 异常未捕获:

    • 如果在事务中的代码块中抛出未捕获的异常,事务可能会失效。确保在事务代码块中适当地捕获和处理异常。

  2. 未设置自动提交:

    • 默认情况下,MyBatis 是开启自动提交的。如果手动设置了 autoCommitfalse,但没有手动提交事务,可能会导致事务失效。

    sqlSession.getConnection().setAutoCommit(false);

  3. 手动提交后的继续执行:

    • 如果在手动提交事务后继续执行其他 SQL 语句,可能会导致事务失效。确保在提交事务后不再执行其他需要事务保护的操作。

    sqlSession.commit();
    // 继续执行其他 SQL 语句
  4. 并发控制问题:

    • MyBatis 默认是不处理并发控制的,如果有多个线程同时修改同一行数据,可能会出现并发问题。在需要并发控制的场景,可以考虑使用数据库提供的锁机制或乐观锁。

确保了解 MyBatis 事务的底层机制,并在代码中正确地使用事务管理,可以避免事务失效的问题。在处理异常和提交事务时,要特别注意保持事务的一致性。

  • 33
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值