Eclipselink JPA MySQL предотвращает параллелизм транзакций - PullRequest
0 голосов
/ 25 февраля 2019

У меня есть ситуация, когда данные имеют параллелизм в транзакции.

Пример: пользователь 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Мне все еще нужно применить пессимистическую блокировку?

Может быть, кто-то может мне помочь, чтобы предотвратить параллелизм в транзакциях?

Заранее спасибо.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...