2016-09-30 2 views
0

Я хочу, чтобы обновить пользовательскую таблицу, когда два потока работают вместе, что бросает «Строка была обновлена ​​или удалена другой транзакцией (или неверное сопоставление неверно): [com .dmainc.commons.security.User # 4] " . Когда второй поток обращается в первую очередь, начинается откат и исключение. Фактически каждый поток изменяет парольAttemptDate.I нужно обновлять это поле каждый раз, когда пользователь регистрируется, как выполнять эту операцию одновременно для обоих потоков. Я вызываю этот метод внутри транзакции.Строка была обновлена ​​или удалена другой транзакцией-многопотоком

ЛЮБОЕ ПРЕДЛОЖЕНИЕ БУДЕТ ОЦЕНИВАЕТСЯ.

public AuthenticationStatus authenticateEncrypted(User user, String password, ISecurityParameters params, 
    Boolean encryptedPassword) 
    { 
    AuthenticationStatus status = new AuthenticationStatus(); 
    status.setUser(user); 
    status.setStatus(AuthenticationStatus.Status.UNKNOWN_ERROR); 

    // hash password 
    String hashedPass = (encryptedPassword == true ? password : hashPassword(password, user.getSalt())); 

    // compare to stored password and check on attempts if failed 
    if(hashedPass.equals(user.getPassword())) 
    { 
     user.setPasswordAttempts(0); 
     //THIS IS GETTING UPDATED EACH TIME 
     user.setPasswordAttemptDate(Calendar.getInstance()); 

     if(getPasswordNotify(user, params) >= 0) 
     { 
      status.setStatus(AuthenticationStatus.Status.SUCCESS_NOTIFY); 
     } 
     else if(isPasswordExpired(user, params)) 
     { 
      status.setStatus(AuthenticationStatus.Status.PASSWORD_EXPIRED); 
     } 
     else 
     { 
      status.setStatus(AuthenticationStatus.Status.SUCCESS); 
     } 

     status.setArg(arg); 
     return status; 
    } 
    else 
    { 
     user.setPasswordAttempts((user.getPasswordAttempts() == null) ? 1 : user.getPasswordAttempts() + 1); 
     user.setPasswordAttemptDate(Calendar.getInstance()); 
     status.setStatus(AuthenticationStatus.Status.FAIL); 
    } 
    } 
    catch(Exception pe) 
    { 
    if(LOG.isErrorEnabled()) 
     LOG.error(pe, pe); 
    } 

    return status; 

}

User.hbm.xml

<hibernate-mapping> 
<class name="com.dmainc.commons.security.User" table="userdata"> 
    <id name="userId" type="long"> 
     <column name="UserId" /> 
     <generator class="native" /> 
    </id> 
    <version name="version" type="int"> 
     <column name="Version" not-null="true" /> 
    </version> 
    <property name="username" type="string"> 
     <column name="Username" length="50" not-null="true" /> 
    </property> 
    <property name="firstName" type="string"> 
     <column name="FirstName" length="50" /> 
    </property> 
    <property name="lastName" type="string"> 
     <column name="LastName" length="50" /> 
    </property> 
    <property name="email" type="string"> 
     <column name="Email" length="50" /> 
    </property> 
    <property name="status" type="string"> 
     <column name="Status" length="2" /> 
    </property> 

    <property name="passwordAttempts" type="int"> 
     <column name="PasswordAttempts" /> 
    </property> 
    <property name="passwordAttemptDate" type="calendar"> 
     <column name="PasswordAttemptDate" length="19" /> 

    <many-to-one name="organization" class="com.dmainc.commons.security.Organization" fetch="select"> 
     <column name="OrganizationId" /> 
    </many-to-one> 
    <set name="userpasswords" table="userpasswords" inverse="true" lazy="true" fetch="select" cascade="all,delete-orphan"> 
     <key> 
      <column name="UserId" not-null="true" /> 
     </key> 
     <one-to-many class="com.dmainc.commons.security.UserPassword" /> 
    </set> 
    <bag name="userroles" table="userrole" inverse="true" lazy="false" fetch="select" cascade="all,delete-orphan"> 
     <key> 
      <column name="UserId" not-null="true" /> 
     </key> 
     <one-to-many class="com.dmainc.commons.security.UserRole" /> 
    </bag> 
</class> 

+0

Вы должны использовать Session.lock (Object entitty, LockMode замок). Как правило, вы либо хотите использовать LockMode.PESSIMISTIC_WRITE или LockMode.UPGRADE_NOWAIT. Последний вариант работает только для систем БД, поддерживающих выбор ..... для обновления синтаксиса ожидания (например, Oracle, Sql-сервер). Обратите внимание, что при изменении режимов блокировки вам может потребоваться увеличить тайм-аут trasacaction) –

+0

, когда я удалил версию из hbm ее работоспособности, может ли это быть возможным исправлением? Какое влияние будет удалять ?, @dsp_user – Surya

+0

Возможно, потому что Hibernate использует для оптимистическая блокировка (https://www.intertech.com/Blog/versioning-optimistic-locking-in-hibernate/) –

ответ

0

Вы можете попробовать ограждающих код в блоках транзакций?

что-то вроде:

Session session = null; 
Transaction tx = null; 

try { 
session = sessionFactory.openSession(); 
tx = session.beginTransaction(); 
//YOUR CODE HERE 

tx.commit(); 

}catch (Exception ex) { 
ex.printStackTrace(); 
tx.rollback(); 
} 
finally {session.close();} 
Смежные вопросы

 Смежные вопросы