TransactionRequiredException при сохранении объекта [duplicate]

Некоторые статистические данные, связанные с этим известным вопросом с двойной точностью.

При добавлении всех значений ( a + b ) с шагом 0,1 (от 0,1 до 100) имеем ~ 15% вероятность ошибки точности. Обратите внимание, что ошибка может привести к несколько большим или меньшим значениям. Вот несколько примеров:

0.1 + 0.2 = 0.30000000000000004 (BIGGER)
0.1 + 0.7 = 0.7999999999999999 (SMALLER)
...
1.7 + 1.9 = 3.5999999999999996 (SMALLER)
1.7 + 2.2 = 3.9000000000000004 (BIGGER)
...
3.2 + 3.6 = 6.800000000000001 (BIGGER)
3.2 + 4.4 = 7.6000000000000005 (BIGGER)

При вычитании всех значений ( a - b , где a> b ) с шагом 0,1 (от 100 до 0,1), мы имеем вероятность 34% точности. Вот несколько примеров:

0.6 - 0.2 = 0.39999999999999997 (SMALLER)
0.5 - 0.4 = 0.09999999999999998 (SMALLER)
...
2.1 - 0.2 = 1.9000000000000001 (BIGGER)
2.0 - 1.9 = 0.10000000000000009 (BIGGER)
...
100 - 99.9 = 0.09999999999999432 (SMALLER)
100 - 99.8 = 0.20000000000000284 (BIGGER)

* 15% и 34% действительно огромны, поэтому всегда используйте BigDecimal, когда точность имеет большое значение. С 2 десятичными цифрами (шаг 0,01) ситуация несколько ухудшается (18% и 36%).

5
задан BalusC 5 March 2016 в 09:13
поделиться

3 ответа

В основном один находится в присутствии контекста сохранения JTA, управляемого контейнером, с транзакциями, управляемыми бобами (BMT).

Поэтому, помимо вашего EntityManager, вы также должны ввести в свой DataFetchBean ваш UserTransaction, чтобы начать, совершить или отменить транзакцию.

@Named
@RequestScoped
public class DataFetchBean {
    @PersistenceContext
    EntityManager em;

    @Resource
    private UserTransaction userTransaction;

    ...
}

Затем, в вашем addEmployee методе, вы должны начать и затем совершить транзакцию, поэтому ваши изменения на ваш сотрудник может быть распространен в базу данных.

public void addEmployee() throws Exception {
    Employee employee = new Employee(500000, new Date(335077446), "Josh", "Carribean", 'm', new Date(335077446));

    userTransaction.beginTransaction();
    em.persist(employee);
    userTransaction.commit();
}

Несмотря на это, вам следует подумать о переносе действий базы данных в EJB, вставляя их в свой JSF-компонент, поэтому делегирование на контейнере (например, использовать CMT вместо ручной обработки).

8
ответ дан aribeiro 26 August 2018 в 21:54
поделиться

Вы можете увидеть ниже документ о транзакции: Транзакции, управляемые контейнером JEE6

используют Transaction Attributes на основе вашей заявки

0
ответ дан alireza alallah 26 August 2018 в 21:54
поделиться

Альтернативный способ справиться с этим - использовать аннотацию @Transactional для вашего метода DataFetchBean addEmployee. Тогда вам не понадобится UserTransaction и вы можете использовать AOP для управления транзакцией.

Это была новая функция, добавленная в JTA 1.2.

5
ответ дан John Ament 26 August 2018 в 21:54
поделиться
Другие вопросы по тегам:

Похожие вопросы: