Skip to contentMethod: EntityTransactionImpl(EntityTransactionWrapper)
1: /**
2: * Copyright (C) 2016 Czech Technical University in Prague
3: * <p>
4: * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public
5: * License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later
6: * version.
7: * <p>
8: * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
9: * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
10: * details. You should have received a copy of the GNU General Public License along with this program. If not, see
11: * <http://www.gnu.org/licenses/>.
12: */
13: package cz.cvut.kbss.jopa.transactions;
14:
15: import cz.cvut.kbss.jopa.exceptions.RollbackException;
16: import cz.cvut.kbss.jopa.utils.ErrorUtils;
17: import org.slf4j.Logger;
18: import org.slf4j.LoggerFactory;
19:
20: import java.util.Objects;
21:
22: public class EntityTransactionImpl implements EntityTransaction {
23:
24: private static final Logger LOG = LoggerFactory.getLogger(EntityTransactionImpl.class);
25:
26: private boolean active = false;
27:
28: private boolean rollbackOnly = false;
29:
30: private final EntityTransactionWrapper wrapper;
31:
32: public EntityTransactionImpl(EntityTransactionWrapper wrapper) {
33: super();
34: this.wrapper = Objects.requireNonNull(wrapper, ErrorUtils.constructNPXMessage("wrapper"));
35: }
36:
37: /**
38: * Starts the current transaction.
39: *
40: * @throws IllegalStateException if the transaction is already active
41: */
42: @Override
43: public void begin() {
44: if (isActive()) {
45: throw new IllegalStateException("Transaction already active!");
46: }
47: wrapper.begin();
48: this.active = true;
49: wrapper.getEntityManager().transactionStarted(this);
50: LOG.trace("EntityTransaction begin.");
51: }
52:
53: /**
54: * Commit the current transaction.
55: *
56: * @throws IllegalStateException when the transaction is not active
57: */
58: @Override
59: public void commit() {
60: if (!isActive()) {
61: throw new IllegalStateException("Cannot commit inactive transaction!");
62: }
63: try {
64: LOG.trace("EntityTransaction commit started.");
65: if (rollbackOnly) {
66: throw new RollbackException("Trying to commit transaction marked as rollback only.");
67: } else {
68: try {
69: wrapper.getTransactionUOW().commit();
70: } catch (RuntimeException ex) {
71: wrapper.getEntityManager().removeCurrentPersistenceContext();
72: throw new RollbackException(ex);
73: }
74: }
75: } finally {
76: if (wrapper.getTransactionUOW().shouldReleaseAfterCommit()) {
77: wrapper.getEntityManager().removeCurrentPersistenceContext();
78: }
79: cleanup();
80: LOG.trace("EntityTransaction commit finished.");
81: }
82: }
83:
84: private void cleanup() {
85: this.active = false;
86: this.rollbackOnly = false;
87: wrapper.setTransactionUOW(null);
88: wrapper.getEntityManager().transactionFinished(this);
89: }
90:
91: /**
92: * Roll back the current transaction. Dismiss any changes made.
93: *
94: * @throws IllegalStateException when the transaction is not active
95: */
96: @Override
97: public void rollback() {
98: if (!isActive()) {
99: throw new IllegalStateException("Cannot rollback inactive transaction!");
100: }
101: wrapper.getTransactionUOW().rollback();
102: wrapper.getEntityManager().removeCurrentPersistenceContext();
103: cleanup();
104: LOG.trace("EntityTransaction rolled back.");
105: }
106:
107: /**
108: * Mark this transaction as rollback only. I. e. the only possible outcome of this transaction is rollback.
109: *
110: * @throws IllegalStateException when the transaction is not active
111: */
112: @Override
113: public void setRollbackOnly() {
114: if (!isActive()) {
115: throw new IllegalStateException("Cannot set rollbackOnly on inactive transaction!");
116: }
117: this.rollbackOnly = true;
118: }
119:
120: /**
121: * Is is this transaction marked as rollbackOnly?
122: *
123: * @throws IllegalStateException when the transacion is not active
124: */
125: @Override
126: public boolean isRollbackOnly() {
127: if (!isActive()) {
128: throw new IllegalStateException("Accessing rollbackOnly on inactive transaction!");
129: }
130: return this.rollbackOnly;
131: }
132:
133: @Override
134: public boolean isActive() {
135: return active;
136: }
137:
138: /**
139: * Roll back any changes if we forgot to commit or roll it back manually
140: */
141: @Override
142: public void finalize() throws Throwable {
143: if (isActive()) {
144: rollback();
145: }
146: super.finalize();
147: }
148:
149: }