# 事务控制

使用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 %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://taocares.gitbook.io/development-guide/kai-fa-zhi-nan/shi-wu-kong-zhi.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
