> For the complete documentation index, see [llms.txt](https://taocares.gitbook.io/development-guide/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://taocares.gitbook.io/development-guide/kai-fa-zhi-nan/shi-wu-kong-zhi.md).

# 事务控制

使用Spring Data JPA的`JpaRepository`或者其实现时，数据持久层对原生方法默认已经开启了事务，无需人工干预。

{% hint style="info" %}
原生方法是指`JpaRepository`中已经提供的方法。
{% endhint %}

{% hint style="info" %}
本文中的“事务”均指本地事务。考虑到性能等问题，不使用分布式事务。
{% endhint %}

## 数据持久层

在自己实现的数据持久层中，对于`JpaRepository`中未提供的方法，默认采用只读事务。因此，对于修改数据的方法，需要配置`@Transactional`注解，开启非只读事务。

{% code title="FooRepository.java" %}

```java
package com.example.demo.repository;

import com.example.demo.entity.Foo;
import org.springframework.data.jpa.repository.*;
import org.springframework.data.repository.query.Param;

import javax.transaction.Transactional;
import java.util.List;

public interface FooRepository extends JpaRepository<Foo, Long>, JpaSpecificationExecutor<Foo> {

    List<Foo> findByName(String name);

    @Transactional
    @Query("update Foo set name = :name where id = : id")
    void updateName(@Param("id") Long id, @Param("name") String name);
}
```

{% endcode %}

## 业务逻辑层

在业务逻辑层中，有时候需要组合多种资源完成特定的操作。此时，为保证数据一致性，通常需要在业务逻辑层增加事务控制。

{% code title="CompositeService.java" %}

```java
package com.example.demo.service;

import com.example.demo.repository.BarRepository;
import com.example.demo.repository.FooRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.transaction.Transactional;

@Service
public class CompositeService {
    @Autowired
    private FooRepository fooRepository;
    @Autowired
    private BarRepository barRepository;

    @Transactional
    public void compositeMethod() {
        fooRepository.doSomething();
        barRepository.doSomething();
    }
}
```

{% endcode %}

{% hint style="info" %}
仅当所有资源均为本地资源时，本地事务才起作用。分布式环境下，建议采用事件驱动的方式实现最终一致性。
{% endhint %}

{% hint style="warning" %}
仅在修改数据的方法上增加事务控制，切忌在查询方法启用非只读事务。
{% endhint %}
