简体   繁体   English

并发请求中的剩余api数据不匹配

[英]rest api data mismatch in concurrent request

In my project we are using restful webservices with spring framework, when I call the same request concurrently the property of the object is overriden by one another. 在我的项目中,我们在Spring框架中使用了宁静的Web服务,当我同时调用同一请求时,该对象的属性将被彼此覆盖。

Below is my code. 下面是我的代码。

@Service("testService")
@Scope(value ="prototype")
public class TestServiceImpl extends DefaultServiceBuilder {

        public void test() {
                 process();
                 System.err.println(tranLog.getTxnId());

        }
}


  public class DefaultServiceBuilder {

protected TransactionLog tranLog;

public void process() {
    tranLog = new TransactionLog();
    Random r = new Random();
    String rid = r.nextInt(40000)+"";
    tranLog.setTxnid(rid);
    setTranLog(tranLog);
}


    public TransactionLog getTranLog() {
        return tranLog;
    }

    public void setTranLog(TransactionLog tranLog) {
        this.tranLog = tranLog;
    }
}

public class TransactionLog {
   private String txnId;

   public void setTxnId(String txnId) {
        this.txnId = txnId;
   }

   public String getTxnId() {
        return txnId;
   }
}

I am calling the below request with 2 thread parallel. 我正在用2个线程并行调用以下请求。

My expected input is 
123456
242422

But the output is 
242422
242422

Why the TransactionLog object value is overriding eventhough i gave scope prototype. 尽管我给出了作用域原型,但为什么仍覆盖了TransactionLog对象的值。 How to access the Transalog object safely? 如何安全地访问Transalog对象?

Any help will be greatly Appreciated!!!! 任何帮助将不胜感激!!!!

You could synchronize your code, by synchronizing below line of code 您可以通过同步下面的代码行来同步代码

protected static TransactionLog tranLog;

public static synchronized void process() {
    Random r = new Random();
    tranLog = new TransactionLog();
    String rid = r.nextInt(40000)+"";
    tranLog.setTxnid(rid);
}

Making static synchronized will allow only one thread at any given time. 使static synchronized将在任何给定时间仅允许一个线程。

Class name TransactionLog implies that evety instance of TransactionLog , writed to variable tranLog will be used only in one thread. 类名TransactionLog意味着写入变量tranLogTransactionLog的完整实例将仅在一个线程中使用。

If it right, then read further: 如果正确,请进一步阅读:

In very good book "Java Concurrency in Practice" described one good pattern of thread synchronization: 在非常好的书《 Java Concurrency in Practice》中,描述了一种线程同步的良好模式:

Thread Confinement 线程限制

Accessing shared, mutable data requires using synchronization; 访问共享的可变数据需要使用同步。 one way to avoid this requirement is to not share. 避免此要求的一种方法是不共享。 If data is only accessed from a single thread, no synchronization is needed. 如果仅从单个线程访问数据,则不需要同步。 This technique, thread confinement, is one of the simplest ways to achieve thread safety. 这种技术,即线程限制,是实现线程安全的最简单方法之一。 When an object is confined to a thread, such usage is automatically thread-safe even if the confined object itself is not [CPJ 2.3.2]. 当一个对象被限制在一个线程中时,即使该限制对象本身不是[CPJ 2.3.2],这种使用也是自动线程安全的。

Make field tranLog just local variable 使字段tranLog只是局部变量

final TransactionLog tranLog = new TransactionLog();

If you use it in other function, for instance subProcess2 : 如果在其他功能中使用它,例如subProcess2

private void subProcess2() {
    tranLog.doSometthing();
}

Add tranLog to function parameters: tranLog添加到函数参数:

private void subProcess2(TransactionLog tranLog) {
    tranLog.doSometthing();
}

And pass tranLog when calling subProcess2 . 并呼吁subProcess2时通过tranLog。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM