服务器之家:专注于服务器技术及软件下载分享
分类导航

Mysql|Sql Server|Oracle|Redis|MongoDB|PostgreSQL|Sqlite|DB2|mariadb|Access|数据库技术|

服务器之家 - 数据库 - Mysql - SpringBoot注解@Transactional详解以及事务失效

SpringBoot注解@Transactional详解以及事务失效

2023-09-28 03:43未知服务器之家 Mysql

一、事务的特点ACID 原子性(Atomicity): 事务最小的执行单位,不允许分割,事务的原子性确保动作要么全部完成,要么完全失败。 一致性(Consistency): 执行事务前后,数据保持一致,例如在上面的转账例子中,无论事务是否成

一、事务的特点ACID

  • 原子性(Atomicity):事务最小的执行单位,不允许分割,事务的原子性确保动作要么全部完成,要么完全失败。
  • 一致性(Consistency):执行事务前后,数据保持一致,例如在上面的转账例子中,无论事务是否成功,转账者和收款人的总额应该是不变的。
  • 隔离性(Isolation):并发访问数据库时,一个用户的事务不被其它事务干扰,各并发事务之间的数据库是独立的。
  • 持久性(Durability):一个事务被提交后,它对数据库中数据的改变是持久的,即使数据库发生故障也不应该对其有任何影响。

二、Spring对事务的支持

程序是否支持事务的先决条件是数据库,比如使用MySQL的话,如果选择的是innodb,那么支持事务,如果选择的是myisam,那么从根上就不支持事务了

MySQL怎么保证原子性?

如果要保证原子性,就需要在发生异常时,对已经执行的操作进行回滚,在MySQL中,恢复机制是通过回滚日志实现的,所有事务进行的修改,都会先记录到这个回滚日志中,然后再执行相关的操作。

如果在执行过程中遇到异常,我们直接利用回滚日志中的信息将数据回滚到修改之前的样子即可,并且回滚日志会先将数据持久化到磁盘上,这样就可以保证即便在遇到数据库突然宕机,当用户再次重启数据库时,数据库还是能够通过查回滚日志来回滚之前未完成的事务。

三、Spring支持两种事务管理

3.1编程事务管理

通过TransactionTemplate或者TransactionManager手动管理事务,在实际应用中却很少使用,下面通过代码来演示,使用TransactionTemplate进行编程式事务管理

@Autowired
private TransactionTemplate transactionTemplate;

public void testTransactionTemplate() {
  transactionTemplate.execute(new TransactionCallbackWithoutResult() {
    protected void doInTransactionWithoutResult(final TransactionStatus transactionStatus) {
      try {
        //TODO 业务代码
      } catch (final Exception e) {
        // 异常时回滚
        transactionStatus.setRollbackOnly();
      }
    }
  });
}

使用TransactionManager进行编程式事务管理

@Resource
private PlatformTransactionManager transactionManager;

public void testTransactionManager() {
  final TransactionStatus status = transactionManager.getTransaction(new DefaultTransactionDefinition());
  try {
    //TODO 业务代码
    transactionManager.commit(status);
  } catch (final Exception e) {
    // 异常时回滚
    transactionManager.rollback(status);
  }
}

3.2声明式事务管理

声明式事务管理,实际上是通过AOP实现,基于@Transactional的注解使用最多

@Transactional
public void testTransactional() {
  userInfoDao.save(userInfo);
  userInfoDetailDao.save(userInfoDetail);
}

在实际的业务开发中,大家一般使用@Transactional注解来开启事务,但很多人并不是很清楚这个注解中的参数是什么意思?有什么用?

3.2.1@Transactional的作用范围

  • 方法推荐将注解用于方法上,不过需要注意的是:该注解只能应用到 public 方法上,否则不生效。
  • :如果将注解用在类上,表明该类中所有的 public 方法都生效。
  • 接口:不推荐在接口上使用。

@Transactional注解源码如下,里面包含了基本事务属性的配置:

package org.springframework.transaction.annotation;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Transactional {
  String value() default "";

  Propagation propagation() default Propagation.REQUIRED;

  Isolation isolation() default Isolation.DEFAULT;

  int timeout() default -1;

  boolean readOnly() default false;

  Class<? extends Throwable>[] rollbackFor() default {};

  String[] rollbackForClassName() default {};

  Class<? extends Throwable>[] noRollbackFor() default {};

  String[] noRollbackForClassName() default {};
}

@Transactional 的常用参数介绍

属性名

说明

propagation

事务的传播行为,默认值为 REQUIRED

isolation

事务的隔离级别,默认值采用 DEFAULT

timeout

事务的超时时间,默认值为-1(不会超时),如果超过该时间限制但事务还没有完成,则自动回滚事务

readOnly

指定事务是否为只读事务,默认值为 false

rollbackFor

用于指定能够触发事务回滚的异常类型,并且可以指定多个异常类型

关于传播行为propagation属性:

  • REQUIRED:支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。
  • SUPPORTS:支持当前事务,如果当前没有事务,就以非事务方式执行。
  • MANDATORY:支持当前事务,如果当前没有事务,就抛出异常。
  • REQUIRES_NEW:新建事务,如果当前存在事务,把当前事务挂起。
  • NOT_SUPPORTED:以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
  • NEVER:以非事务方式执行,如果当前存在事务,则抛出异常。
  • NESTED:支持当前事务,如果当前事务存在,则执行一个嵌套事务,如果当前没有事务,就新建一个事务。

3.2.2@Transactional失效场景

  1. 非 public 修饰的方法;
  2. timeout 超时时间设置过小;
  3. 代码中使用 try/catch 处理异常;
  4. 调用类内部的@Transactional 方法;
  5. 数据库不支持事务。

延伸 · 阅读

精彩推荐
  • MysqlERROR: Error in Log_event::read_log_event()

    ERROR: Error in Log_event::read_log_event()

    ERROR: Error in Log_event::read_log_event(): read error, data_len: 438, event_type: 2 ...

    MYSQL教程网6412020-03-13
  • MysqlMySQL数据库varchar的限制规则说明

    MySQL数据库varchar的限制规则说明

    本文我们主要介绍了MySQL数据库中varchar的限制规则,并以一个实际的例子对限制规则进行了说明,希望能够对您有所帮助。 ...

    mysql技术网4192019-11-23
  • MysqlMySQL 数据备份与还原的示例代码

    MySQL 数据备份与还原的示例代码

    这篇文章主要介绍了MySQL 数据备份与还原的相关知识,本文通过示例代码给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下...

    逆心2972019-06-23
  • MysqlMySQL锁的知识点总结

    MySQL锁的知识点总结

    在本篇文章里小编给大家整理了关于MySQL锁的知识点总结以及实例内容,需要的朋友们学习下。...

    别人放弃我坚持吖4362020-12-14
  • Mysql详解MySQL中的分组查询与连接查询语句

    详解MySQL中的分组查询与连接查询语句

    这篇文章主要介绍了MySQL中的分组查询与连接查询语句,同时还介绍了一些统计函数的用法,需要的朋友可以参考下 ...

    GALAXY_ZMY5442020-06-03
  • Mysqlmysql 不能插入中文问题

    mysql 不能插入中文问题

    当向mysql5.5插入中文时,会出现类似错误 ERROR 1366 (HY000): Incorrect string value: '\xD6\xD0\xCE\xC4' for column ...

    MYSQL教程网5722019-11-25
  • Mysql浅谈mysql 树形结构表设计与优化

    浅谈mysql 树形结构表设计与优化

    在诸多的管理类,办公类等系统中,树形结构展示随处可见,本文主要介绍了mysql 树形结构表设计与优化,具有一定的参考价值,感兴趣的小伙伴们可以参...

    小码农叔叔5242021-11-16
  • Mysql解决MySQl查询不区分大小写的方法讲解

    解决MySQl查询不区分大小写的方法讲解

    今天小编就为大家分享一篇关于解决MySQl查询不区分大小写的方法讲解,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起...

    Veir_dev5592019-06-25