У меня есть ситуация, когда данные имеют параллелизм в транзакции.
Пример: пользователь 1 создает транзакцию 1 с элементом 1 кол-во 3 и элементом 2 кол-во 5. Пользователь 2 создает транзакцию 2 с элементом 1 кол-во 6 иЭлемент 2 кол-во 7.
Каждый элемент имеет каждый собственный баланс (например, на складе, элемент на входе и выходе).
Как я могу предотвратить параллелизм между этим балансом элемента из элементов 1 и 2правильно, если транзакция 1 и транзакция 2 выполняются одновременно от пользователей diffrence?
Элемент 1 должен иметь баланс 9 (3 + 6), а не 3 или 6, из-за перезаписи.Пункт 2 должен иметь баланс 12 (5 + 7).
У меня был опыт в ColdFusion.Когда я использовал функцию cftransaction, каждый sql-запрос будет блокировать данные и таблицу (не всю таблицу, только в cftransaction) до вызова commit или rollback (исправьте меня, если я неправильно понял).
Что до сих пор я применяю:
В файле persistence.xml
<property name="eclipselink.session.customizer"
value="com.sft.FlexiSessionCustomizer" />
В файле Java:
public class FlexiSessionCustomizer implements SessionCustomizer {
@Override
public void customize(Session session) throws Exception {
DatabaseLogin databaseLogin = (DatabaseLogin) session
.getDatasourceLogin();
databaseLogin
.setTransactionIsolation(DatabaseLogin.TRANSACTION_SERIALIZABLE);
}
}
Метод вставки (это чистая вставка в базу данных):
public boolean insertDataBean(Object data) {
if (data == null) {
logger.error("Data is not valid.");
return false;
}
boolean result = true;
EntityManager em = this.createEntityManager();
data.setCreatedDate(new Timestamp((new Date()).getTime()));
EntityTransaction entr = em.getTransaction();
try {
entr.begin();
em.persist(data);
entr.commit();
} catch (Exception e) {
logger.error("ERROR INSERT : " + data.getClass().getName() + " | "
+ e.getMessage());
result = false;
}
em.close();
return result;
}
Вызовметод вставки:
insertDataBean(transaction1); // from user 1
insertDataBean(transaction2); // from user 2
Этого достаточно, чтобы предотвратить параллелизм?
Что я думаю, может быть, мне следует изменить код вставки следующим образом:
public boolean insertDataBean(Object data) {
if (data == null) {
logger.error("Data is not valid.");
return false;
}
boolean result = true;
EntityManager em = this.createEntityManager();
data.setCreatedDate(new Timestamp((new Date()).getTime()));
EntityTransaction entr = em.getTransaction();
try {
entr.begin();
// all code, like read item balance and calculation item balance?
// should query use the same entity manager (em) or new entity manager will be the same?
em.persist(data);
// Other code transaction
entr.commit();
} catch (Exception e) {
logger.error("ERROR INSERT : " + data.getClass().getName() + " | "
+ e.getMessage());
result = false;
}
em.close();
return result;
}
DoМне все еще нужно применить пессимистическую блокировку?
Может быть, кто-то может мне помочь, чтобы предотвратить параллелизм в транзакциях?
Заранее спасибо.