[英]Propagation of new transactions (using REQUIRES_NEW) in a loop is not working as expected
I am not sure why the following is not working. 我不确定以下原因为何不起作用。 I want new transactions to begin in a loop (propagation = REQUIRES_NEW).
我希望新事务以循环开始(传播= REQUIRES_NEW)。 And every transaction should be committed before a new transaction is fired in this loop.
并且在此循环中触发新事务之前,应提交每个事务。 However, only the first iteration of the loop executes and then then nothing happens.
但是,仅执行循环的第一次迭代,然后什么也没有发生。
@Service
@Transactional
public class Aimpl implements A {
@Autowired
private B b;
private Logger logger = LoggerFactory.getLogger(this.getClass());
public void methodA(List<Customer> customers){
logger.info("before loop"); //gets printed
customers.forEach(customer -> {
logger.info("1"); //--> this gets printed
b.processEachCustomer(customer);
logger.info("2"); //- this does not get printed
});
logger.info("after loop"); //does not get printed
}
}
//-----------------Second class----------
@Service
@Transactional
public class Bimpl implements B {
@Autowired
private MyRepository repository;
private Logger logger = LoggerFactory.getLogger(this.getClass());
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void processEachCustomer(Customer customer){
//process each customer - a new transaction everytime
//and it should be committed independently
repository.updateCustomerData(customer.getId());
logger.info("3");//this does not get printed
}
}
This is my repository class that just issues an update query in a table for one row. 这是我的存储库类,它仅在表中针对一行发出更新查询。
public interface MyRepository extends Repository<Customer , Long> {
@Modifying
@Query("UPDATE Customer c SET c.status = 1 WHERE i.id= :id")
int setStatusById(@Param("id") Integer id);
}
What am I doing wrong here? 我在这里做错了什么? Basically, why does only the first iteration of the loop work and the rest do not?
基本上,为什么只有循环的第一次迭代才起作用,而其余的为什么不起作用? I am trying to debug it and do not see the application stopping at the breakpoint after the first iteration.
我正在尝试调试它,并且看不到应用程序在第一次迭代后在断点处停止。
方法A将使用默认范围创建事务,因为@Transactional在类级别。
This worked fine when I removed the annotation from the methodA() and also removed class level transactional annotation in class Aimpl. 当我从methodA()中删除注释,并且还删除了类Aimpl中的类级别事务性注释时,此方法运行良好。
@Service
public class Aimpl implements A {
@Autowired
private B b;
private Logger logger = LoggerFactory.getLogger(this.getClass());
public void methodA(List<Customer> customers){
customers.forEach(customer -> {
b.processEachCustomer(customer);
});
}
}
//-----------------Second class---------- // -----------------第二类----------
@Service
@Transactional
public class Bimpl implements B {
@Autowired
private MyRepository repository;
private Logger logger = LoggerFactory.getLogger(this.getClass());
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void processEachCustomer(Customer customer){
//process each customer - a new transaction everytime
//and it should be committed independently
repository.updateCustomerData(customer.getId());
}
}
EDIT 2: Let me correct myself here. 编辑2:让我在这里纠正自己。 This works fine even if I do not remove transactional annotation from the method and let the class stay annotated with transactional.
即使我不从方法中删除事务性注释并使类保持事务性注释,此方法也能正常工作。 The real issue here was a deadlock that was happening on the database level due to lock acquired by some other process.
真正的问题是死锁,由于其他进程获取的锁,该死锁正在数据库级别发生。 The code is correct as it is.
该代码是正确的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.