Эта статья знакомит вас с весенними делами

Java Spring

предисловие

Только лысая голова может стать сильнее.

Текст был включен в мой репозиторий GitHub, добро пожаловать, звезда:GitHub.com/Zhongf UC очень…

Я считаю, что все часто используют управление транзакциями Spring, но оно может быть ограничено только одним@Transactionalпримечание или вXMLНастройте материалы, связанные с транзакциями, в . Во всяком случае, каждый деньвозможныйДостаточно для нас, чтобы использовать. Но как программист, будь то для интервью или лучшего контроля над кодом, который вы пишете, вы должны больше узнать о деталях транзакций Spring.

Здесь я задаю несколько вопросов, чтобы посмотреть, сможете ли вы ответить на них мгновенно:

  • есливложенные вызовыМетод, содержащий транзакцию, к какой точке знаний он относится в управлении транзакциями Spring?
  • Фреймворк, который мы используем, может бытьHibernate/JPAилиMybatisизвестно, что нижний слой нуждается вsession/connectionобъекты, помогающие нам выполнять операции. Чтобы обеспечить целостность транзакций, нам нужно использовать несколько наборов операций с базой данных.тот самыйsession/connectionObject, и мы знаем, что объекты, управляемые Spring IOC, по умолчаниюсинглтонДа, почему мы не вызовем проблем с безопасностью потоков при его использовании? Что именно Spring делает внутри?
  • Что люди называют БПП?
  • Каковы важные интерфейсы управления весенней транзакцией?

Во-первых, прочитайте основы, необходимые для этой статьи

Мои одноклассники, прочитавшие эту статьюдефолтУ каждого есть определенное понимание знаний, связанных с транзакциями Spring. (ps: если вы не понимаете конкретную статью, прочитайте ее и вернитесь сюда)

Мы все знаем, что транзакция Spring — одна из лучших практик Spring AOP, так что скажемБазовые знания входа в АОП (простая настройка, использование)нужно знать в первую очередь. Если вы хотите узнать больше об АОП, вы можете прочитать эту статью:Важные точки знаний АОП (введение в терминологию, всестороннее использование). Когда дело доходит до АОП, мы должны сказатьОсновополагающий принцип АОП: динамический шаблон проектирования прокси.. На данный момент у нас уже есть базовое понимание АОП. Так что мы можемИспользуйте XML/аннотацию для настройки управления транзакциями Spring.

В исследовании МОК можно узнать следующее:Жизненный цикл Beans in Spring (извлечение объектов BPP)иОбъекты, управляемые IOC, по умолчанию являются одноэлементными: шаблон проектирования одноэлементного, если одноэлементный объект имеет "государство"(с переменными-членами) несколько потоков, обращающихся к этому одноэлементному объекту, могут привести к небезопасности потока. ТогдаЧто такое потокобезопасность?, есть много способов решить потокобезопасность, но один из них:Пусть у каждого потока будет своя переменная: ThreadLocal

Если вы не очень хорошо разбираетесь в пунктах знаний, о которых я упоминал выше, рекомендуется щелкнуть синее слово, чтобы узнать его.

2. Два примера ненадежной интуиции

2.1 Первый пример

Друг задал мне пример раньше:

Бросить исключение на уровне сервиса и поймать его на уровне контроллера.Если в сервисе есть исключение, будет ли отменена транзакция?



// Service方法
	
@Transactional
public Employee addEmployee() throws Exception {

    Employee employee = new Employee("3y", 23);
    employeeRepository.save(employee);
	// 假设这里出了Exception
    int i = 1 / 0;

    return employee;
}

// Controller调用
@RequestMapping("/add")
public Employee addEmployee() {
    Employee employee = null;
    try {
        employee = employeeService.addEmployee();
    } catch (Exception e) {
        e.printStackTrace();
    }
    return employee;

}

япервая реакция: Не откатится.

  • Тогда я подумал: потому что сервисный уровень выдал исключение, перехваченное контроллером. Откат или нет должен определяться логикой в ​​блоке кода перехвата контроллера.Если блок кода перехвата не откатывается, его не следует откатывать.

Но мой друг сказал после тестирования, что его можно откатить. (папапа бьет по лицу)

发生了运行时Exception,Spring事务管理自动回滚

Глядя на документацию, в исходной документации говорится:

By default checked exceptions do not result in the transactional interceptor marking the transaction for rollback and instances of RuntimeException and its subclasses do

Вывод: если это исключение времени компиляции, оно не будет автоматически откатываться,Если это исключение во время выполнения, оно автоматически откатится!

2.2 Второй пример

Второй пример взят из статьи Zhihu @ willow, соответствующий URL-адрес будет указан в конце статьи.

Мы все знаем, что с@TransactionalМетод, заключенный в аннотации, может управляться транзакциями Spring, тогда, если яИспользуйте нетранзакционный метод для вызова транзакционного метода в текущем классе, что будет с нашим звонком на этот раз? Будет ли бизнес?

Опишите это в коде:


// 没有事务的方法去调用有事务的方法
public Employee addEmployee2Controller() throws Exception {

    return this.addEmployee();
}

@Transactional
public Employee addEmployee() throws Exception {

    employeeRepository.deleteAll();
    Employee employee = new Employee("3y", 23);

    // 模拟异常
    int i = 1 / 0;

    return employee;
}

Мой первый инстинкт: это связано с механизмом распространения транзакций Spring.

На самом деле это связано с механизмом распространения транзакций Spring.это не имеет значения, позвольте мне сказать вам:

  • Управление транзакциями Spring использует АОП, а нижний уровень АОП использует динамический прокси. Итак, если мы пометим аннотацию в классе или методе@Transactional, затемпрокси-объект.

Далее позвольте мне проиллюстрировать это картинкой:

Spring会自动生成代理对象

Очевидно, что мы получаем прокси (Proxy) объект, вызовaddEmployee2Controller()метод, в то время какaddEmployee2Controller()Логика метода такова.target.addEmployee(), который вызывает исходный объект (цель)addEmployee().所以这次的调用Бизнеса нет вообще, не говоря уже о механизме распространения транзакций Spring.

Исходные данные:

原有的数据

Результат теста: транзакции нет вообще

没有事务的存在

2.2.1 Расширьте его еще немного

Из приведенного выше теста мы можем обнаружить, что если в этом классе нет метода транзакции для вызова аннотации аннотации@Transactionalметода, окончательный вывод заключается в том, что транзакции нет. Затем, если я аннотирую метод этой аннотациейперейти кСуществуют ли какие-либо транзакции с другими объектами службы?


@Service
public class TestService {

    @Autowired
    private EmployeeRepository employeeRepository;
    
    @Transactional
    public Employee addEmployee() throws Exception {

        employeeRepository.deleteAll();

        Employee employee = new Employee("3y", 23);

        // 模拟异常
        int i = 1 / 0;

        return employee;
    }

}


@Service
public class EmployeeService {

    @Autowired
    private TestService testService;
    // 没有事务的方法去调用别的类有事务的方法
    public Employee addEmployee2Controller() throws Exception {
        return testService.addEmployee();
    }
}


Результаты теста:

抛出了运行时异常,但我们的数据还是存在的!

Поскольку мы используем прокси-объект (Proxy) для вызоваaddEmployee()метод, то, конечно, есть бизнес.

Прочитав эти два примера, как вы думаете,3-летняя интуиция - настоящая вода!

3. Механизм распространения транзакций Spring

есливложенные вызовыМетод, содержащий транзакцию, к какой точке знаний он относится в управлении транзакциями Spring?

в текущемСодержит методы транзакций, которые вызывают другие методы внутри(независимо от того, содержит метод транзакцию или нет), это относится к категории точек знаний механизма распространения транзакций Spring.

Транзакции Spring основаны на Spring AOP, динамическом прокси-сервере, используемом в нижней части Spring AOP.Существует два способа динамического прокси:

  • Прокси на основе интерфейса (прокси JDK)
    • На основе прокси интерфейса любой метод классазакрытая модификация,илиИспользуется статическое ключевое словоукрашение, эти методы не могут быть улучшены с помощью Spring AOP
  • На основе прокси-сервера CGLib (прокси подкласса)
    • На основе прокси подкласса любой метод классаИспользовать приватную, статическую, окончательную модификацию, то ни один из этих методов нельзя улучшить с помощью Spring AOP.

Что касается того, почему описанную выше ситуацию нельзя улучшить, просто подумайте об этом своими мозгами, и вы поймете.

Стоит отметить: те методы, которые нельзя улучшить с помощью Spring AOPНе можетРаботал в деловой среде. пока ониВызывается методом внешней транзакции, из-за уровня распространения управления транзакциями Spring внутренние методы также могутРаботаинициируется внешним методомв контексте транзакции.

Что касается нескольких уровней механизма распространения транзакций Spring, я не буду их здесь публиковать. Это просто для того, чтобы еще раз объяснить, «какова область действия механизма распространения транзакций Spring».

В-четвертых, проблема многопоточности

Фреймворк, который мы используем, может бытьHibernate/JPAилиMybatisизвестно, что нижний слой нуждается вsession/connectionобъекты, помогающие нам выполнять операции. Чтобы гарантировать целостность транзакции, нам нужноНесколько групп операций с базой данных должны использовать один и тот жеsession/connectionObject, и мы знаем, что объекты, управляемые Spring IOC, по умолчаниюсинглтонДа, почему мы не вызовем проблем с безопасностью потоков при его использовании? Что именно Spring делает внутри?

Вспомните, как мы писали Mybaits, когда училисьКласс инструмента сеанса?

Mybatis工具类部分代码截图

Да, используется ThreadLocal, и Spring тоже использует ThreadLocal.

Следующий контент взят из «Освоение Spring 4.x»

Мы знаем, что, как правило, только Bean без сохранения состояния может использоваться совместно только в многопоточной среде, в Spring подавляющее большинство Bean может быть объявлено как одноэлементная область. Spring обусловлен тем, что некоторые компоненты Bean (такие как RequestContextHolder,TransactionSynchronizationManager, LocaleContextHolder и т. д.) «объекты состояния», которые не являются потокобезопасными, инкапсулируются ThreadLocal, что делает их также потокобезопасными «объектами состояния».

Мы можем попробовать щелкнуть TransactionSynchronizationManager, чтобы посмотреть:

全都是ThreadLocal

5. Что такое ППП?

Полное название BBP называется: BeanPostProcessor, обычно мы называем егопостпроцессор объекта

  • Проще говоря, через BeanPostProcessor мы можем "Обработка".

Управляемые bean-компоненты Spring (или жизненный цикл Bean) также являютсяобычный тестОчки знаний, я также набираю осеньюсноваЯ разобрал шаги, потому что это важнее, поэтому выложу здесь:

  1. ResouceLoader загружает информацию о конфигурации
  2. BeanDefintionReader анализирует информацию о конфигурации и генерирует BeanDefintion один за другим.
  3. BeanDefintion управляется BeanDefintionRegistry
  4. BeanFactoryPostProcessor обрабатывает информацию о конфигурации (то есть обрабатывает информацию о конфигурации, обычно реализуемую через PropertyPlaceholderConfigurer)
  5. создавать экземпляры бобов
  6. если фасоль配置/实现Если InstantiationAwareBean установлен, вызовите соответствующий метод
  7. Используйте BeanWarpper для завершения настройки атрибутов (зависимости) между объектами.
  8. если фасоль配置/实现了Осведомленный интерфейс, затем вызовите соответствующий метод
  9. Если Bean сконфигурирован с помощью метода before BeanPostProcessor, он вызывается
  10. Если bean-компонент сконфигурирован сinit-methodИли реализуйте InstantiationBean, затем вызовите соответствующий метод
  11. Если Bean настроен с помощью метода after BeanPostProcessor, он вызывается
  12. Поместить объекты в HashMap
  13. Наконец, если настроен метод destroy или DisposableBean, выполняется операция уничтожения.

Application中Bean的声明周期

Также есть фотографии про БПП:

BBP所在的位置

5.1 Почему вы конкретно говорите о BPP?

Нижний уровень программирования Spring AOP — технология динамического прокси, которую необходимо использовать при вызовепрокси-объект. Так как же это делает Spring?

Мне нужно только написать BPP, в методе PostProcessfoediNiTialization или постпроцессафициализации или постпроцессафициализации, судите объект, чтобы увидеть, нужно ли оно вплетено в аспектную логику, при необходимости, я буду генерировать прокси-объект на основе этого объекта, а затем вернуть Прокси-объект, то окончательная инъекция в контейнер, естественно, является прокси-объектом.

Spring предоставляет BeanPostProcessor, который позволяет нам "Обработка"Какие!

6. Поймите несколько важных интерфейсов транзакций Spring

Транзакции Spring можно разделить на два типа:

  • Программные транзакции (реализация транзакций с помощью кода)
  • Декларативные транзакции (транзакции реализуются конфигурацией)

Программные транзакции относительно просто реализовать в Spring, а декларативные транзакции реализовать гораздо сложнее, потому что они инкапсулируют множество вещей (обычно мы используем простые, а они очень сложные).

В программных транзакциях есть несколько важных интерфейсов:

  • TransactionDefinition: определяет Spring-совместимыйСвойства транзакции(например, уровень изоляции транзакций, распространение транзакций, тайм-аут транзакции, статус только для чтения)
  • TransactionStatus: представляет специфику транзакции.Рабочий статус(Чтобы получить информацию о текущем статусе транзакции, вы также можете использовать этот интерфейскосвенныйоткат транзакций и др.)
  • PlatformTransactionManager: интерфейс диспетчера транзакций (определяет набор поведений, а конкретная реализация выполняется с помощью различных платформ сохраняемости ---аналогияJDBC)

PlatformTransactionManager解析

В декларативных транзакциях помимо интерфейсов TransactionStatus и PlatformTransactionManager есть несколько важных интерфейсов:

  • TransactionProxyFactoryBean: создание прокси-объектов
  • TransactionInterceptor: Реализовать перехват объекта
  • TransactionAttrubute: данные конфигурации транзакции.

Наконец

В этой статье в основном рассказывается о некоторых наиболее важных знаниях об управлении транзакциями Spring.Конечно, в процессе обучения есть и другие знания.Если вы хотите продолжить обучение, вы можете продолжить чтение справочных материалов, приведенных ниже. .

Использованная литература:

  • В те годы мы вместе гонялись за Весной
  • «Знание практики разработки корпоративных приложений Spring 4.x»
  • "Инсайдер технологии Spring"

рад вывестигалантерейные товарыОбщедоступный номер технологии Java: Java3y. В паблике более 200 статейоригинальныйТехнические статьи, обширные видеоресурсы, красивые карты мозга — идите сюдаобрати внимание нанемного!

帅的人都关注了

Я думаю, что моя статья хорошо написана, пожалуйста, нажмитеотличный!