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

时间:2022-10-23 19:34:38

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框架的restful webservices,当我同时调用相同的请求时,对象的属性被彼此覆盖。

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. How to access the Transalog object safely?

为什么TransactionLog对象值覆盖了尽管我给了范围原型。如何安全地访问Transalog对象?

Any help will be greatly Appreciated!!!!

任何帮助将不胜感激!!!!

2 个解决方案

#1


1  

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.

进行静态同步将在任何给定时间仅允许一个线程。

#2


1  

Class name TransactionLog implies that evety instance of TransactionLog, writed to variable tranLog will be used only in one thread.

类名TransactionLog意味着TransactionLog的evety实例,写入变量tranLog只能在一个线程中使用。

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。

#1


1  

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.

进行静态同步将在任何给定时间仅允许一个线程。

#2


1  

Class name TransactionLog implies that evety instance of TransactionLog, writed to variable tranLog will be used only in one thread.

类名TransactionLog意味着TransactionLog的evety实例,写入变量tranLog只能在一个线程中使用。

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。