Java 1) 使用@Transactional获取其他线程的提交值,2)回滚4个不同服务的所有异常事务

Java 1) 使用@Transactional获取其他线程的提交值,2)回滚4个不同服务的所有异常事务,java,postgresql,spring-boot,spring-data-jpa,spring-transactions,Java,Postgresql,Spring Boot,Spring Data Jpa,Spring Transactions,我有两个彼此相关的问题。我使用的是SpringBootJPA 问题-1 我必须提交4个不同的服务。我从控制器级别一个接一个地调用这些服务。任何服务上的失败都必须回滚其他已提交的事务。 例如。, 如果控制器方法调用线程1和, i) 服务1事务成功 ii)服务2交易成功 iii)如果服务3事务失败-则服务1和服务2事务必须回滚 问题2 我正在更新服务-1上的唯一列值。首先读取实体,获取最后一行的值,增加它的值,然后再次保存。 但当另一个线程调用相同的进程时,它会读取以前读取的相同实体,并且重复值会发

我有两个彼此相关的问题。我使用的是SpringBootJPA

问题-1 我必须提交4个不同的服务。我从控制器级别一个接一个地调用这些服务。任何服务上的失败都必须回滚其他已提交的事务。 例如。, 如果控制器方法调用线程1和, i) 服务1事务成功 ii)服务2交易成功 iii)如果服务3事务失败-则服务1和服务2事务必须回滚

问题2 我正在更新服务-1上的唯一列值。首先读取实体,获取最后一行的值,增加它的值,然后再次保存。 但当另一个线程调用相同的进程时,它会读取以前读取的相同实体,并且重复值会发生错误。 例如

线程1呼叫服务1 1) 读取线程1的实体 2) 获取值,比方说-100 3) 增值至-101 4) 保存实体 5) 现在其他线程调用相同的服务

线程2呼叫服务1 1) 读取线程2的实体 2) 获取值是-100,而不是101 它给出了错误,因为在保存线程1的实体后,它应该读取更新的值,即线程2的101。但目前,我得到了未提交的值

我在这里上传实体、控制器、服务和存储库级别的代码

//Entity Level

@Entity
@Data
public class MyEntity {

    private Long id;

    @Column(unique = true)
    private Long uniqueCode;
}

@Entity
@Data
public class MyOtherEntity{
    private Long id;
}

//Repository Level

@Repository
public interface MyEntityRepository extends JpaRepository<MyEntity, Long> {
    MyEntity findFirstByOrderByIdDesc();
}

@Repository
public interface MyOtherEntityRepository extends JpaRepository<MyOtherEntity, Long> {
}


//Controller Level

@Controller
public class MyController {

    @Autowired
    private MyService myService;


    @PostMapping("/updateData")
    @ResponseBody
    public String updateData(){

        myService.updateDataForEntity();

        myService.updateDataForOtherEntity();

        myService.myThirdServiceCall();

        myService.myFourthServiceCall();

        return "success";
    }
}


//Service Level

@Service
public class MyService{

    @Autowired
    MyEntityRepository myEntityRepository;

    @Autowired
    MyOtherEntityRepository myOtherEntityRepository;

    @Synchronized // Using to prevent other thread call, however error occurs
    @Transactional // I have used previously (isolation = Isolation.SERIALIZABLE), but not get any result
    public void updateDataForEntity() {
        try {
            //Get last unique code value - HERE I GOT SAME VALUE FOR OTHER THREAD (T-2) THOUGH THREAD-1 WAS SAVED 
            MyEntity oldEntity = myEntityRepository.findFirstByOrderByIdDesc();

            //Set updated unique code value and save
            MyEntity newEntity = new MyEntity();
            newEntity.setUniqueCode(oldEntity.getUniqueCode() + 1L);
            myEntityRepository.save(newEntity);
        } catch (Exception e) {
            //Should Rollback
        }
    }

    public void updateDataForOtherEntity() {
        try {
            MyOtherEntity myOtherEntity = new MyOtherEntity();
            myOtherEntityRepository.save(myOtherEntity);
        } catch (Exception e) {
            //Must rollback on exception for Service-1
        }
    }

    public void myThirdServiceCall() {
        try {

        } catch (Exception e) {
            // Must rollback on exception for Service-2 and service-1 call
        }
    }

    public void myFourthServiceCall() {
        try {
        } catch (Exception e) {
            // Must rollback on exception for Third Service Call, Service-2 and service-1 call
        }
    }
}
//实体级
@实体
@资料
公共类MyEntity{
私人长id;
@列(唯一=真)
专用长唯一码;
}
@实体
@资料
公共类实体{
私人长id;
}
//存储库级别
@存储库
公共接口MyEntityRepository扩展了JpaRepository{
MyEntity findFirstByOrderByIdDesc();
}
@存储库
公共接口MyOtherEntityRepository扩展了JpaRepository{
}
//控制器级
@控制器
公共类MyController{
@自动连线
私人MyService-MyService;
@后映射(“/updateData”)
@应答器
公共字符串updateData(){
myService.updateDataForEntity();
myService.updateDataForOtherEntity();
myService.myThirdServiceCall();
myService.myFourthServiceCall();
返回“成功”;
}
}
//服务水平
@服务
公共类MyService{
@自动连线
髓质沉积性髓质沉积性;
@自动连线
肌红蛋白沉积;肌红蛋白沉积;
@已同步//用于防止其他线程调用,但发生错误
@事务//我以前使用过(隔离=隔离.SERIALIZABLE),但没有得到任何结果
public void updateDataForEntity(){
试一试{
//获取最后一个唯一的代码值-在这里,我为其他线程(T-2)获取了相同的值,尽管保存了线程1
MyEntity oldEntity=myEntityRepository.findFirstByOrderByIdDesc();
//设置更新后的唯一代码值并保存
MyEntity newEntity=新MyEntity();
newEntity.setUniqueCode(oldEntity.getUniqueCode()+1L);
myEntityRepository.save(新实体);
}捕获(例外e){
//应该回滚
}
}
public void updateDataForOtherEntity(){
试一试{
MyOtherEntity MyOtherEntity=新的MyOtherEntity();
myOtherEntityRepository.save(myOtherEntity);
}捕获(例外e){
//必须在服务-1发生异常时回滚
}
}
公共无效myThirdServiceCall(){
试一试{
}捕获(例外e){
//必须回滚服务2和服务1调用的异常
}
}
public void myFourthServiceCall(){
试一试{
}捕获(例外e){
//必须在第三个服务调用、服务2和服务1调用发生异常时回滚
}
}
}
我已经阅读了有关事务传播级别和隔离级别的教程。但请指导我,我可以使用@Transactional的哪种方法来解决上述两个问题