Spring事务抽象
1 介绍Spring框架事务管理
全面的事务支持是使用Spring框架令人信服的原因。Spring框架为事务管理提供一致性抽象,拥有以下好处:
一致性编程模型跨不同事务APIs,例如,Java事务API(JTA)、JDBC、Hibernate、Java持久化API(JPA)和Java数据对象(JDO)。
支持声明式事务管理。
比复杂事务APIs(例如,JTA)更简单。
完美的与Spring的数据访问抽象集成。
2 Spring框架的事务支持模型的优点
传统上,Java EE开发人员有两种可选的事务管理方式:全局或本地事务,都有各自的局限性。
2.1 全局事务
全局事务让你能使用多个事务资源,通常是关系型数据库和消息队列。应用程序通过JTA管理全局事务,这是一个笨重的API。而且,JTA UserTransaction通常需要来自JNDI,意味着你需要使用JNDI。显然,使用全局事务会限制应用程序代码的重用,因为JTA通常只在应用程序服务器环境有效。
以往,使用全局事务的首选方式是通过EJB CMT(容器管理事务):CMT是声明式事务管理。EJB CMT清除了相关事务的JNDI查找,不过EJB自己需要使用JNDI。它清除大多数(但不是所有)需要编写Java代码控制事务。重要的缺点是,CMT捆绑JTA和应用程序服务器环境。同时,它只有使用EJBs实现业务逻辑,或至少在事务EJB门面中时才有效。
2.2 本地事务
本地事务时特定资源,例如,事务关联JDBC连接。本地事务易于使用,但有明显缺点:它们不能跨多个事务资源。例如,使用JDBC连接管理事务不能运行在全局JTA事务中。因为应用程序服务器没有负责事务管理,它不保证跨资源的正确性。另一个缺点是本地事务时入侵式编程模型。
2.3 Spring框架的一致性编程模型
Spring解决了全局和本地事务的缺点。它让开发人员在任意环境使用一致性编程模型。开发人员只需编写自己的代码,它能抽离不同环境中的不同的事务管理。Spring框架提供声明式和编程式事务管理。大多数用户喜欢声明式事务管理,这也是推荐的。
使用编程式事务管理,开发人员使用Spring框架事务抽象,能运行在任意底层事务之上。使用首选的声明式模型,开发人员通常写很少或不写事务管理代码,因此,不依赖于Spring框架事务API,或其它事务API。
3 理解Spring框架事务抽象
Spring事务抽象的关键是事务策略的概念。事务策略通过org.springframework.transaction.PlatformTransactionManager接口定义:
public interface PlatformTransactionManager {
TransactionStatus getTransaction(
TransactionDefinition definition) throws TransactionException;
void commit(TransactionStatus status) throws TransactionException;
void rollback(TransactionStatus status) throws TransactionException;
}
这主要是服务提供接口(SPI),尽管它能在你的代码中使用编程模型。因为PlatformTransactionManager是一个接口,它易于模拟(mocked)和存根(stubbed)。它不需要像JNDI一样查找策略。PlatformTransactionManager实现像Spring IoC容器中定义的其它对象一样。这个好处让Spring框架事务值得抽象,甚至是使用JTA时。事务代码比直接使用JTA易于测试。
PlatformTransactionManager接口方法抛出的TransactionException是未检测异常(即,继承java.lang.RuntimeException)。事务失败是致命性的。很少情况,应用程序代码能实际从事务失败中恢复,应用程序开发人员能选择捕获并处理TransactionException。优点在于开发人员不必强制这样做。
getTransaction(..)方法依赖于TransactionDefinition参数返回TransactionStatus对象。返回的TransactionStatus可以代表一个新事务,或如果匹配事务在当前调用栈中存在则代表已存在的事务。其实就是后面这种情况,正如Java EE事务上下文,TransactionStatus关联可执行的事务。
TransactionDefinition接口说明:
Isolation(事务隔离级别):事务隔离级别。例如,该事务是否能读取其它的未提交事务?
Propagation(事务传播):通常,所有代码执行在事务范围将运行在事务中。然而,你有一个选项可以指定当事务上下文已存在时事务方法执行的行为。例如,代码能继续运行在已存在的事务中(通常情况);或已存在的事务暂停,创建一个新事务。
事务超时:该事务运行多长时间后失效,并通过底层事务自动回滚。
只读状态:当你的代码读取但不修改数据时,可以使用只读事务。在某些情况下,只读事务有利于优化,例如,当你使用Hibernate时。
这些设置反应标准事务概念。底层这些概念是使用Spring框架或任意事务管理解决方案不可或缺的。
TransactionStatus接口为事务代码提供简单的方式控制可执行事务和查询事务状态:
public interface TransactionStatus extends SavepointManager {
boolean isNewTransaction();
boolean hasSavepoint();
void setRollbackOnly();
boolean isRollbackOnly();
void flush();
boolean isCompleted();
}
无论你是否选择Spring中的声明式或编程式事务管理,定义正确的PlatformTransactionManager实现是必不可少的。你通常通过依赖注入定义该实现。
PlatformTransactionManager通常需要知道工作的环境:JDBC、JTA、Hibernate等等。下面是定义本地PlatformTransactionManager的例子。
定义JDBC DataSource:
destroy-method="close">
PlatformTransactionManager定义引用DataSource定义:
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
如果你在Java EE容器中使用JTA,那么你可以通过使用JNDI和Spring的JtaTransactionManager获取容器的DataSource:
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jee="http://www.springframework.org/schema/jee" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee.xsd">
JtaTransactionManager不需要知道DataSource,或任意特定资源,因为它使用容器的全局事务管理。
你也能使用Hibernate的本地事务。在这种情况下,你需要定义Hibernate的LocalSessionFactoryBean,你的应用程序代码将使用它获取Hibernate Session实例。
这种情况下,txManager bean是HibernateTransactionManager。正如DataSourceTransactionManager需要引用DataSource一样,HibernateTransactionManager需要引用SessionFactory:
hibernate.dialect=${hibernate.dialect}
如果你使用Hibernate和Java EE容器管理JTA事务,那么你只用使用JtaTransactionManager:
在所有这些情况下,应用程序代码不需要改变。你仅仅需要改变配置来改变如何管理事务。
4 使用事务同步资源
现在应该清楚如何创建不同的事务管理器,和它们如何链接需要同步事务的相关资源(例如,DataSourceTransactionManager链接DataSource,HibernateTransactionManager链接SessionFactory等等)。
4.1 高级同步方式
首选方式是使用Spring的高级模板基于持久化集成APIs或使用带有事务的本地ORM APIs——感知工厂bean或代理管理本地资源工厂。这些事务感知解决方案内部处理资源创建、重用、清理、资源事务同步选项和异常映射。因此,数据访问代码没有处理这些任务,但可以关注非样板式持久化逻辑。通常,你使用本地ORM API或通过使用JdbcTemplate获取模板。
4.2 低级同步方式
例如,DataSourceUtils(JDBC)、EntityManagerFactoryUtils(JPA)、SessionFactoryUtils(Hibernate)、PersistenceManagerFactoryUtils(JDO)存在底层同步方式。当你想应用程序代码直接处理本地持久化APIs,你使用这些类确保获取Spring框架管理的实例,事务是(可选)同步的,发生在进程中的异常正确映射一致性API。
例如,在JDBC的情况下,传统的JDBC方式在DataSource上调用getConnection()方法,你可以使用Spring的org.springframework.jdbc.datasource.DataSourceUtils:
Connection conn = DataSourceUtils.getConnection(dataSource);
如果已存在的事务已经有一个连接同步(链接)它,实例被返回。否则,方法调用触发器创建新的连接,(可选)同步任意已存在的事务,后续在相同事务中重用。
这种方式不需要Spring事务管理(事务同步是可选的),因此,无论你是否使用Spring管理事务你都能使用它。
当然,一旦你使用Spring的JDBC支持、JPA支持或Hibernate支持,你通常不喜欢使用DataSourceUtils或其它的帮助类。
4.3 TransactionAwareDataSourceProxy
在底层,已经存在TransactionAwareDataSourceProxy类。这是目标DataSource代理,包装目标DataSource到感知Spring管理事务。为此,它类似于Java EE服务器提供的传统JNDI DataSource。
5 声明式事务管理
Spring框架的声明式事务管理让Spring面向切面编程(AOP)成为可能,尽管,Spring框架发布包以模板形式自带事务切面代码,一般需要理解AOP。
5.1 理解Spring框架的声明式事务实现
通过元数据驱动事务通知(当前基于XML或注解)。AOP联合事务元数据产生AOP代理,使用TransactionInterceptor联合适当的PlatformTransactionManager实现驱动事务环绕方法调用。
5.2 声明式事务实现的例子
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
5.3 回滚声明式事务
默认情况下,只有抛出运行时异常或Error时导致Spring事务回滚。检查异常不导致Spring事务回滚。
你能明确配置事务回滚的异常类型。
你也能指定事务不会滚的异常类型:
5.4 为不同的bean配置不同的事务语义
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
5.5
默认设置:
事务传播设置是REQUIRED
事务隔离级别是DEFAULT
事务是读/写
事务超时时间默认为底层事务系统的超时时间,或如果不支持超时就没有
任意RuntimeException异常触发回滚,任意检查Exception不触发
你能改变这些默认设置;嵌套在
5.6 使用@Transactional
开启注解管理事务:
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
Service声明注解:
@Transactional
public class DefaultFooService implements FooService {
Foo getFoo(String fooName);
Foo getFoo(String fooName, String barName);
void insertFoo(Foo foo);
void updateFoo(Foo foo);
}
@Transactional设置:
@Transactional的多事务管理器:
public class TransactionalService {
@Transactional("order")
public void setSomething(String name) { ... }
@Transactional("account")
public void doSomething() { ... }
}
class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> ...
class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> ...
自定义简称注解
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Transactional("order")
public @interface OrderTx {
}
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Transactional("account")
public @interface AccountTx {
}
5.7 事务传播
PROPAGATION_REQUIRED
当设置事务传播为PROPAGATION_REQUIRED时,为每个方法创建一个逻辑事务范围。每个逻辑事务范围能单独决定只回滚状态,外部事务范围逻辑独立于内部事务范围。当然,在标准的PROPAGATION_REQUIRED情况下,所有这些范围将映射相同的物理事务。因此,只回滚标记设置在内部事务范围不影响外部事务发生的实际提交。
然而,在这种情况下,内部事务范围设置为只回滚标记,外部事务没有决定回滚,因此回滚是意想不到的。相应的UnexpectedRollbackException抛出。
PROPAGATION_REQUIRES_NEW
对比PROPAGATION_REQUIRED,PROPAGATION_REQUIRES_NEW使用完全独立的事务。在这种情况下,底层物理事务是不同的,因此,能独自提交或回滚,外部事务的回滚状态不受内部事务的影响。
PROPAGATION_NESTED
使用一个能回滚到多个保存点的物理事务。这种回滚允许内部事务范围触发它的范围回滚,外部事务能够继续物理事务,尽管一些操作已经回滚。该设置通常映射到JDBC保存点,因此,只能用于JDBC资源事务。
6 编程式事务管理
Spring框架提供两种编程式事务管理:
使用TransactionTemplate(推荐)
使用PlatformTransactionManager直接实现
6.1 使用TransactionTemplate
TransactionTemplate采用与其它Spring模板(例如,JdbcTemplate)相同的方式。
public class SimpleService implements Service {
private final TransactionTemplate transactionTemplate;
public SimpleService(PlatformTransactionManager transactionManager) {
Assert.notNull(transactionManager, "The 'transactionManager' argument must not be null.");
this.transactionTemplate = new TransactionTemplate(transactionManager);
}
public Object someServiceMethod() {
return transactionTemplate.execute(new TransactionCallback() {
public Object doInTransaction(TransactionStatus status) {
updateOperation1();
return resultOfUpdateOperation2();
}
});
}
}
如果没有返回值,则使用TransactionCallbackWithoutResult类:
transactionTemplate.execute(new TransactionCallbackWithoutResult() {
protected void doInTransactionWithoutResult(TransactionStatus status) {
updateOperation1();
updateOperation2();
}
});
在业务代码中回滚:
transactionTemplate.execute(new TransactionCallbackWithoutResult() {
protected void doInTransactionWithoutResult(TransactionStatus status) {
try {
updateOperation1();
updateOperation2();
} catch (SomeBusinessExeption ex) {
status.setRollbackOnly();
}
}
});
指定事务设置:
public class SimpleService implements Service {
private final TransactionTemplate transactionTemplate;
public SimpleService(PlatformTransactionManager transactionManager) {
Assert.notNull(transactionManager, "The 'transactionManager' argument must not be null.");
this.transactionTemplate = new TransactionTemplate(transactionManager);
this.transactionTemplate.setIsolationLevel(
TransactionDefinition.ISOLATION_READ_UNCOMMITTED);
this.transactionTemplate.setTimeout(30); // 30秒
}
}
使用Spring XML配置TransactionTemplate:
class="org.springframework.transaction.support.TransactionTemplate">
6.2 使用PlatformTransactionManager
DefaultTransactionDefinition def = new DefaultTransactionDefinition();
def.setName("SomeTxName");
def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
TransactionStatus status = txManager.getTransaction(def);
try {
// 执行业务逻辑
} catch (MyException ex) {
txManager.rollback(status);
throw ex;
}
txManager.commit(status);
7 选择编程式还是声明式管理事务?
如果你只有少量事务操作选择编程式事务管理。
8 事务绑定事件
从Spring 4.2开始,监听器事件可以绑定到事务阶段。
@Componentpublic class MyComponent {
@TransactionalEventListener
public void handleOrderCreatedEvent(CreationEvent
...
}
}
TransactionalEventListener注解暴露phase属性允许定制监听事务阶段。有效的阶段是:BEFORE_COMMIT、AFTER_COMMIT(默认)、AFTER_ROLLBACK和AFTER_COMPLETION。

Outils d'IA chauds

Undresser.AI Undress
Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover
Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool
Images de déshabillage gratuites

Clothoff.io
Dissolvant de vêtements AI

AI Hentai Generator
Générez AI Hentai gratuitement.

Article chaud

Outils chauds

Bloc-notes++7.3.1
Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise
Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1
Puissant environnement de développement intégré PHP

Dreamweaver CS6
Outils de développement Web visuel

SublimeText3 version Mac
Logiciel d'édition de code au niveau de Dieu (SublimeText3)

En 2023, la technologie de l’IA est devenue un sujet brûlant et a un impact énorme sur diverses industries, notamment dans le domaine de la programmation. Les gens sont de plus en plus conscients de l’importance de la technologie de l’IA, et la communauté Spring ne fait pas exception. Avec l’évolution continue de la technologie GenAI (Intelligence Artificielle Générale), il est devenu crucial et urgent de simplifier la création d’applications dotées de fonctions d’IA. Dans ce contexte, « SpringAI » a émergé, visant à simplifier le processus de développement d'applications fonctionnelles d'IA, en le rendant simple et intuitif et en évitant une complexité inutile. Grâce à « SpringAI », les développeurs peuvent plus facilement créer des applications dotées de fonctions d'IA, ce qui les rend plus faciles à utiliser et à exploiter.

En tant que leader du secteur, Spring+AI fournit des solutions de pointe pour divers secteurs grâce à son API puissante et flexible et ses fonctions avancées. Dans cette rubrique, nous examinerons les exemples d'application de Spring+AI dans divers domaines. Chaque cas montrera comment Spring+AI répond à des besoins spécifiques, atteint ses objectifs et étend ces LEÇONS APPRISES à une gamme plus large d'applications. J'espère que ce sujet pourra vous inciter à comprendre et à utiliser plus profondément les possibilités infinies de Spring+AI. Le framework Spring a une histoire de plus de 20 ans dans le domaine du développement logiciel, et cela fait 10 ans que la version Spring Boot 1.0 est sortie. Maintenant, personne ne peut contester ce printemps

Comment implémenter les transactions programmatiques Spring : 1. Utilisez TransactionTemplate ; 2. Utilisez TransactionCallback et TransactionCallbackWithoutResult ; 3. Utilisez les annotations Transactional ; 4. Utilisez TransactionTemplate en combinaison avec @Transactional ;

Java implémente les tâches planifiées dans la bibliothèque fournie avec Jdk, il existe deux façons d'implémenter les tâches planifiées, l'une est Timer et l'autre est ScheduledThreadPoolExecutor. Lorsque Timer+TimerTask crée un Timer, il crée un thread, qui peut être utilisé pour planifier des tâches TimerTask. Timer a quatre méthodes de construction, et vous pouvez spécifier le nom du thread Timer et s'il doit être défini comme thread démon. Le nom par défaut est Timer-number et il ne s'agit pas d'un thread démon par défaut. Il existe trois méthodes principales : cancel() : mettre fin à la planification des tâches et annuler toutes les tâches actuellement planifiées. purge() : supprimer les tâches de la file d'attente des tâches.

SpringBoot et SpringCloud sont tous deux des extensions de Spring Framework qui aident les développeurs à créer et déployer des applications de microservices plus rapidement, mais elles ont chacune des objectifs et des fonctions différents. SpringBoot est un framework permettant de créer rapidement des applications Java, permettant aux développeurs de créer et de déployer plus rapidement des applications basées sur Spring. Il fournit un moyen simple et facile à comprendre de créer des applications Spring autonomes et exécutables.

Avec la mise à jour et l'itération de la technologie, Java5.0 a commencé à prendre en charge les annotations. En tant que framework leader en Java, Spring a lentement commencé à abandonner la configuration XML depuis sa mise à jour vers la version 2.5, et davantage d'annotations sont utilisées pour contrôler le framework Spring.

Comment définir le niveau d'isolement des transactions dans Spring : 1. Utilisez l'annotation @Transactional ; 2. Définissez-le dans le fichier de configuration Spring ; 3. Utilisez PlatformTransactionManager ; Introduction détaillée : 1. Utilisez l'annotation @Transactional, ajoutez l'annotation @Transactional à la classe ou à la méthode qui nécessite la gestion des transactions et définissez le niveau d'isolement dans l'attribut 2. Dans le fichier de configuration Spring, etc.

En tant que développeur Java, apprendre et utiliser le framework Spring est une compétence essentielle. Avec la popularité du cloud computing et des microservices, apprendre et utiliser Spring Cloud est devenu une autre compétence qui doit être maîtrisée. SpringCloud est un ensemble d'outils de développement basé sur SpringBoot permettant de créer rapidement des systèmes distribués. Il fournit aux développeurs une série de composants, notamment l'enregistrement et la découverte de services, un centre de configuration, l'équilibrage de charge et des disjoncteurs, etc., permettant aux développeurs de créer des micro-ordinateurs.
