提问人:Gaetan L. 提问时间:9/25/2023 最后编辑:Ken ChanGaetan L. 更新时间:9/26/2023 访问量:92
即使没有 @Transactional/@EnableTransactionManagement 的 JPA 事务
JPA transaction even without @Transactional/@EnableTransactionManagement
问:
我正在尝试了解事务如何与 Spring 一起工作。我有一个扩展 CrudRepository 的存储库接口:
@Transactional
public interface MessageRepository extends CrudRepository<Message, Long> {
}
以及我用来创建 EntityManagerFactory 和 TransactionManager 的 PersistenceConfig:
@Configuration
@EnableTransactionManagement
public class PersistenceConfig {
final static Logger logger = LoggerFactory.getLogger(PersistenceConfig.class);
public static EntityManagerFactory emf = null;
@Bean
public PlatformTransactionManager transactionManager() {
return new JpaTransactionManager(entityManagerFactory());
}
@Bean
public EntityManagerFactory entityManagerFactory() {
if (emf == null) {
synchronized (EntityManagerFactory.class) {
if (emf == null) {
final StandardServiceRegistry sr = new StandardServiceRegistryBuilder()
.configure() // Configures setting from hibernate.cfg.xml
.build();
try {
emf = new MetadataSources(sr).buildMetadata().buildSessionFactory();
}
catch (Exception e) {
StandardServiceRegistryBuilder.destroy(sr);
throw e;
}
}
}
}
return emf;
}
}
问题是,我使用记录器来调试 JpaTransactionManager,无论我是否使用注解 @Transactional/@EnableTransactionManager,我都可以看到使用了事务:
3576 [main] DEBUG org.springframework.orm.jpa.JpaTransactionManager - Creating new transaction with name [org.springframework.data.jpa.repository.support.SimpleJpaRepository.save]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT
3576 [main] DEBUG org.springframework.orm.jpa.JpaTransactionManager - Opened new EntityManager [SessionImpl(2090037997<open>)] for JPA transaction
[...]
3576 [main] DEBUG org.springframework.orm.jpa.JpaTransactionManager - Initiating transaction commit
3576 [main] DEBUG org.springframework.orm.jpa.JpaTransactionManager - Committing JPA transaction on EntityManager [SessionImpl(2090037997<open>)]
[...]
3576 [main] DEBUG org.springframework.orm.jpa.JpaTransactionManager - Closing JPA EntityManager [SessionImpl(2090037997<open>)] after transaction
那么,使用这些有什么意义呢?
答:
当方法未使用注释显式声明时,调用事务的原因是:@Transactional
根据文档和 Java 文档
默认情况下,继承自 CrudRepository 的方法继承 来自 SimpleJpaRepository 的事务配置。供阅读 操作时,事务配置 readOnly 标志设置为 真。所有其他配置都配置了一个普通@Transactional,以便 默认事务配置适用。存储库方法 由事务存储库片段提供支持的事务性存储库片段继承事务性存储库片段 实际 fragment 方法中的属性。
要了解有关它的更多详细信息,我建议您阅读文档,主要是 5.1.7。事务性
评论
默认情况下,Spring-data-jpa 将在后台对 上的每个非查询方法进行配置。这意味着即使你没有配置 / ,这些东西仍然存在,因此你会在日志中看到它们。@Transactional
CrudRepository
@Transactional
@EnableTransactionManagement
@Transactional
您可以通过以下方式关闭此类默认行为:
@EnableJpaRepositories(enableDefaultTransactions=false)
其中具有以下含义:enableDefaultTransactions
配置是否启用 Spring Data JPA 的缺省事务 存储 库。默认值为 true。如果禁用,则必须使用存储库 在配置事务的 Fave 后面(例如,使用 Spring 的 注解驱动的事务设施)或存储库方法具有 用于划分交易。
定义和自己定义的意义在于,它为您提供了更大的灵活性来定义所需的事务边界。您可以将其扩展到业务服务方法,甚至更广泛,但不仅限于存储库级别的方法。@EnableTransactionManagement
@Transactional
评论
@Transactional