问题描述
我有一个使用 2 个数据源的服务 - 一个处理读取,一个处理修改操作(插入、删除、更新)。对于每个数据源,我都配置了一个不同的事务管理器。
名为 transactionManager
的默认事务管理器处理读取,而另一个名为 writeTransactionManager
的处理写入。
读取时一切正常,但我有一个 custom delete query
根本没有被正确的事务管理器接收。
这是我的仓库:
public interface DeviceWriteRepository extends JpaRepository<Device,String> {
@Transactional
@Modifying
@Query("DELETE FROM Device d WHERE d.userId = ?1 AND d.tenantId = ?2 AND d.appId = ?3")
void unregisterDevices(String userId,String tenantId,String appId);
}
启用调试和跟踪 JPA/Hibernate 日志后,当我调用 unregisterDevices
设备时,我得到以下日志:
Creating new transaction with name [com.my.app.repository.softDeleteCrudRepositoryImpl.unregisterDevice]: PROPAGATION_required,ISOLATION_DEFAULT
Opened new EntityManager [SessionImpl(1270255427<open>)] for JPA transaction
Exposing JPA transaction as JDBC [org.springframework.orm.jpa.vendor.HibernateJpaDialect$HibernateConnectionHandle@464a9dcc]
delete from device where user_id=? and tenant_id=? and app_id=?
delete from device where user_id=? and tenant_id=? and app_id=?
binding parameter [1] as [VARCHAR] - [user1]
binding parameter [2] as [VARCHAR] - [someTenant]
binding parameter [3] as [VARCHAR] - [someApp]
Initiating transaction commit
Committing JPA transaction on EntityManager [SessionImpl(1270255427<open>)]
Closing JPA EntityManager [SessionImpl(1270255427<open>)] after transaction
一切都很好,如果我检查数据库,删除查询有效,但它没有被 writeTransactionManager
执行。
为了强制使用我想要的事务管理器,我更新了 @Transactional
注释以包含管理器的名称,例如 @Transactional("writeTransactionManager")
,我得到以下异常:
org.springframework.dao.InvalidDataAccessApiUsageException: Executing an update/delete query; nested exception is javax.persistence.TransactionrequiredException: Executing an update/delete query
此外,如果我再次检查日志,我可以看到与第一次尝试不同,writeTransactionManager
实际上是根据以下日志选择的,重点是第一行:
Creating new transaction with name [com.my.app.repository.softDeleteCrudRepositoryImpl.unregisterDevice]: PROPAGATION_required,ISOLATION_DEFAULT; 'writeTransactionManager'
Opened new EntityManager [SessionImpl(1868680430<open>)] for JPA transaction
Exposing JPA transaction as JDBC [org.springframework.orm.jpa.vendor.HibernateJpaDialect$HibernateConnectionHandle@1c459897]
opening JPA EntityManager
Initiating transaction rollback
Rolling back JPA transaction on EntityManager [SessionImpl(1868680430<open>)]
Closing JPA EntityManager [SessionImpl(1868680430<open>)] after transaction
这怎么可能不在交易中,而在初始交易中呢?为什么指定事务管理器的名称会破坏行为?
我还想提到的另一件事是我也尝试过使用 DSL 并定义不同的存储库方法,如下所示:
@Transactional("writeTransactionManager")
void deleteByUserIdAndTenantIdAndAppIdAndplatform(String userId,String appId,PlatformType platform);
当我使用此方法时,writeTransactionManager
被选取,但它首先执行 SELECT
查询以引入托管实体 - 令人惊讶的是 - 删除从未发生。
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)