Java中使用事务(注解实现)

Java中使用事务(注解实现)

事务的介绍

描述: 对于一个功能实现或者业务流程,要么全做,要么全不做!
特性: ACID

  1. A - 原子性:执行的最小单位,要么全做,要么全不做。(undo-log保证)
  2. C - 一致性:事务执行前后,数据库中的数据保持一致。(不一致:丢失修改、脏读、不可重复读、幻读)
  3. I - 隔离性:多个并发的事物之间是相互隔离的。
  4. D - 持久性:事务对数据的修改是永久性的。(redo-log保证)

第一步: 引入依赖

<!-- 项目启动依赖 @Service @Component @RestController tomcat等等 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

第二步:Java代码

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

@Service
public class HelperService {

    @Resource
    private TaskDao taskDao;

    @Resource
    private TaskDetailDao taskDetailDao;

    // isolation:事务的隔离级别,此处使用后端数据库的默认隔离级别, propagation: 如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中(常见)。
    @Transactional(rollbackFor = Exception.class, isolation = Isolation.DEFAULT, propagation = Propagation.REQUIRED)
    public void test(Task task, TaskDetail taskDetail){
        taskDao.saveTask(task);
        int a = 3 / 0;
        taskDetailDao.saveTaskDetail(taskDetail);
    }
}

补充事务的传播行为
在这里插入图片描述
常用的事务传播行为: Propagation.REQUIRED或者Propagation.REQUIRES_NEW

补充事务的隔离级别
(1)DEFAULT
  使用数据库设置的隔离级别(默认),由DBA 默认的设置来决定隔离级别。
(2)READ_UNCOMMITTED
  这是事务最低的隔离级别,它充许别外一个事务可以看到这个事务未提交的数据。
  会出现脏读、不可重复读、幻读 (隔离级别最低,并发性能高)。
(3)READ_COMMITTED
  保证一个事务修改的数据提交后才能被另外一个事务读取。另外一个事务不能读取该事务未提交的数据。
  可以避免脏读,但会出现不可重复读、幻读问题(锁定正在读取的行)。
(4)REPEATABLE_READ(innodb默认的数据库隔离级别)
  可以防止脏读、不可重复读,但会出幻读(锁定所读取的所有行)。
(5)SERIALIZABLE
  这是花费最高代价但是最可靠的事务隔离级别,事务被处理为顺序执行。
  保证所有的情况不会发生(锁表)。
  
注意:myisam与innodb的区别!

  1. myisam只有表级锁,innodb可以支持表级锁和行级锁(默认行级锁)。
  2. myisam强调查询性能,查询操作比innodb快,但是不提供事务支持。innodb提供事务、外键等高级功能,同时具有事务、回滚、崩溃修复能力。
  3. myisam不支持外键,innodb支持外键。
  4. MVCC支持:仅有innodb支持MVCC,同时MVCC只在READ_COMMITTED和REPEATABLE_READ这两个隔离级别下工作。【MVCC:多版本并发控制,使不同事务的读写操作并发执行,提升系统性能。】

第三部: 启动类增加注解

注意一定要启动类开启注解

// 开启注解
@EnableTransactionManagement

补充:事务失效的常见原因

1、 @Transactional必须作用于public方法之上;
2、 @Transactional注解的属性rollbackFor 配置错误,默认只有RuntimeException才会回滚;
3、 启动类没有添加@EnableTransactionManagement
4、 同一个类中调用事务方法,事务会失效

@Service
public class A{

	public void test01(){
	// do something
	test02();
	// do something
	}

	@Transactional(rollbackFor = Exception.class, isolation = Isolation.DEFAULT, propagation = Propagation.REQUIRED)
	public void test02(){
	// do something (操作多个表的增删改)
	}
	
}

5、 异常被捕获了:在事务方法中捕获了异常,事务会失效;
6、 数据库引擎不支持事务;(常见数据库引擎:innodb、bdb支持事务,myisam不支持事务)

### Java使用 `@Transactional` 注解开启事务Java 的 Spring 框架中,`@Transactional` 是最常用的注解之一,用于声明式事务管理。当希望某个方法在一个独立的事务上下文中运行时,在该方法上添加此注解即可。 #### 基本语法 ```java import org.springframework.transaction.annotation.Transactional; @Transactional public void someServiceMethod() { // 方法体... } ``` 为了使 `@Transactional` 生效,还需要确保应用程序上下文已配置了一个合适的平台事务管理器[^1]。 #### 配置事务管理器 通常情况下会定义如下形式的数据源交易管理者: ```xml <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"/> </bean> ``` 或者采用基于 Java Config 方式的配置方式: ```java @Configuration @EnableTransactionManagement public class AppConfig { @Bean public PlatformTransactionManager transactionManager(DataSource dataSource) { return new DataSourceTransactionManager(dataSource); } } ``` #### 自定义属性 除了简单的应用外,有时也需要更细粒度地控制事物行为。这时可以通过设置不同的参数来自定义 `@Transactional` 的功能特性,比如传播行为(propagation),隔离级别(isolation level),超时时间(timeout),只读(read-only flag)等选项[^3]。 例如指定特定的回滚规则以及调整其他参数的例子如下所示: ```java @Transactional( propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, timeout = 30, readOnly = false, rollbackFor = {SQLException.class}, noRollbackFor = {} ) public void complexBusinessOperation(){ // 复杂业务逻辑实现... } ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值