JPA 事务未在方法结束时提交
Posted
技术标签:
【中文标题】JPA 事务未在方法结束时提交【英文标题】:JPA Transaction not commiting at the end of method 【发布时间】:2016-08-30 02:02:29 【问题描述】:我有两种方法:
1:
@Transactional
public Long add(Long clientId)
Contact contact = new Contact();
contact.setClientId(clientId);
contact.setValue('test@test.com');
contact.setType('EMAIL');
contact.setDateStart(new Date());
// autowired repo
return contactRepository.saveAndFlush(contact);
2:
@Transactional(propagation = Propagation.NOT_SUPPORTED)
public void emailsValidator(Long clientId)
Specification<Client> spec = ClientSearchSpecification.getByClientIdWithActiveEmails(clientId);
List<Client> clientList = clientRepository.findAll(spec);
SearchSpecification:
public static Specification<Client> getByClientIdWithActiveEmails(Long clientId)
return (root, query, cb) ->
query.distinct(true);
Join<Client, Contact> clientContactJoin = (Join) root.fetch(Client_.contactList);
List<Predicate> predicates = new ArrayList<>();
predicates.add(cb.equal(root.get(AbstractEntity_.id), clientId));
predicates.add(cb.equal(clientContaktJoin.get(Contakt_.type), 'EMAIL'));
predicates.add(cb.lessThan(clientContaktJoin.get(Contakt_.dateStart), cb.currentTimestamp()));
return cb.and(predicates.toArray(new Predicate[predicates.size()]));
;
主要方法:
@RequestMapping(value = "/clientId/contact/add", method = RequestMethod.POST, produces = "application/json; charset=UTF-8")
public void addContact(@PathVariable(value = "clientId") Long clientId)
contactService.add(clientId);
errorValidationService.emailsValidator(clientId);
我的数据库属性:
hibernate.transaction.auto_close_session: true
hibernate.connection.autocommit: true
org.hibernate.flushMode: COMMIT
问题 - DB 在执行步骤 2 时不包含来自步骤 1 的新实体。仅在所有 rest 调用完成后才提交对象。如何在第 1 步提交实体,以便在第 2 步中选择并加入它?
【问题讨论】:
能否贴出调用这两种方法的代码? 【参考方案1】:原来我在存储库接口中使用了两个不同的@Transaction 实现:
@Transactional
public interface ClientRepository extends JpaRepository<Client, Long>, JpaSpecificationExecutor<Client>
我用过:
import javax.transaction.Transactional;
我应该使用:
import org.springframework.transaction.annotation.Transactional;
这意味着 spring @Transaction 的设置没有被应用,它不能在方法结束时提交自己,它只在调用结束时提交。
【讨论】:
【参考方案2】:您无需承诺选择您的数据(在同一事务中)。
这里的问题是你说过第 2 步需要是 `NOT_SUPPORTED,这意味着第 1 步必须先提交,然后第 2 步才能看到它插入的任何数据。
尝试将第 1 步的传播更改为REQUIRES_NEW
,以确保在进入第 2 步之前提交。
【讨论】:
已经试过了。是的,我可以从步骤 1 中获取所有包含加载实体的 beanList 集合。但是,我不需要所有实体集合,这就是为什么我有自己的搜索条件,例如:cr_date > current_timestamp 和 type = 'something'。当我将任何@Transactions 放在第二种方法上时,Hibernate 会忽略我过滤后的搜索条件,并按该 ID 返回所有链接数据。 你能提供更多关于你如何调用这两种方法的信息吗?它们在同一个物体上吗?您对这些方法的调用者有什么 @Transactional 注释?如果可能,请发布更多代码。以上是关于JPA 事务未在方法结束时提交的主要内容,如果未能解决你的问题,请参考以下文章
SQL 错误“在批处理结束时检测到不可提交的事务”,数据库上没有事务
没有 JPA @Transaction 和 save() 啥时候提交完成?
JPA数据懒加载LAZY配合事务@Transactional使用