Spring concurrency problem - there are state and non-state Bean Bean

First, the state and non-state

Stateful session bean   : each user has their own unique one example, the user's lifetime, bean maintains the user's information, that is "stateful"; Once the user perish (end of the call or the end of the examples), bean lifetime It came to an end. That is, each user will get a first initial bean. Simply put, there is a state data storage capabilities. Stateful objects (Stateful Bean), there is the instance variables of an object, you can save the data, it is not thread-safe of.
Stateless session the bean   : the bean when instanced be added to the session pool, individual users can share. Even if the user is dead, bean lifetime is not necessarily the end, it may still exist in a session in the pool, for other users to call. In the absence of a specific user, then you can not keep a user's status, so called stateless bean. But not without a stateless session bean state, if it has its own attributes (variables), then these variables will affect calls by all its users, it is important to note in practical application. In simple terms, is a stateless operation, data can not be saved. Stateless object (Stateless Bean), is no instance variables of an object. You can not save data, is the same class, are thread-safe.

Package com.sw; 

public  class TestManagerImpl the implements TestManager {
     Private the User User;     // a recording information Examples 

    public  void deleteUser (the User E) throws Exception { 
        User = E;            // . 1 
        prepareData (E); 
    } 

    public  void prepareData ( E the User) throws Exception { 
        User = getUserByID (e.getId ());             // 2 
        .....
         // use user.getId ();                        // . 3
        .....
        .....
    }    
}
A stateful bean
 
Second, the solution stateful bean thread safety issues
There are four ways to configure the Spring bean configuration, we only said two of: singleton singleton, prototype prototype mode.
<bean id="testManager" class="com.sw.TestManagerImpl" scope="singleton" />

<bean id="testManager" class="com.sw.TestManagerImpl" scope="prototype" />

The default configuration is a singleton.

It indicates that the global singleton bean is only one example.

prototype indicates that the bean is injected each time have to re-create an instance, this applies to stateful Bean.

 

If you use a singleton for stateful bean, then thread safety problems.

Examples of the above e.g.

If two users simultaneously access

Assumed to user1, user2

When the call to user1 step 1 of the procedure when the user Bean private variable value is paid user1

When user1 program went 2 steps when the Bean private variable user to be re-paid value user1_create

Ideally, when user1 go to step 3 when the private variable user should user1_create;

But if user1 before the call to step 3, user2 started running to the 1 step, because the resource sharing of a single state, the private variable user is modified to user2

In this case, step 3 is used user1 user.getId () actually used is subject to user2.

In this case we can solve

1. There will bean state configured as a prototype model that allows each thread to create a prototype instance. But this will have a lot of instances consumes more memory space.

2. Use ThreadLocal variable for each thread to set the variable copy.

 

Use ThreadLocal example:

For example, we have PeopleDAO class BankDAO like a bank account and a personal, now need individuals to transfer money to the bank, there is a way to reduce the account in PeopleDAO class, BankDAO class has a method of increasing the account, then the two connection method must use the same database connection object at the time of the call, if they are using two connection objects, will open two transactions, may appear to reduce personal accounts and bank accounts not increase the phenomenon. Use the same Connection object, then the application may be set to a global database connection object to avoid when calling each method to pass a Connection object. The problem is that when we Connection object to the global variable, you can not guarantee that any other thread will close the Connection object, so there will be thread-safety issues. The solution is to transfer during the operation of this thread, using a ThreadLocal get Connection object, so that the call to reduce personal accounts and bank accounts increased thread can take from a ThreadLocal to the same Connection object and the Connection object this unique thread transfer operation will not be affected by other threads, to ensure the thread safety.

public class ConnectionHolder {
    
    public static ThreadLocal<Connection> connectionHolder = new ThreadLocal<Connection>() {
    };
    
    public static Connection getConnection(){
        Connection connection = connectionHolder.get();
        if(null == connection){
            connection = DriverManager.getConnection(DB_URL);
            connectionHolder.set(connection);
        }
        return connection;
    }
 
}

Reference from: https://blog.csdn.net/cs408/article/details/47809271

    https://blog.csdn.net/a236209186/article/details/61460211

    https://blog.csdn.net/u012045045/article/details/84340906

 

Guess you like

Origin www.cnblogs.com/smilepup-hhr/p/11484752.html