Skip to content

Commit 033c5fe

Browse files
committed
sync insert/update db transaction operations to avoid deadlock
1 parent a5ca07a commit 033c5fe

File tree

1 file changed

+22
-10
lines changed

1 file changed

+22
-10
lines changed

src/main/java/de/rwth/idsg/steve/repository/impl/OcppServerRepositoryImpl.java

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,12 @@ public class OcppServerRepositoryImpl implements OcppServerRepository {
4444
@Autowired private DSLContext ctx;
4545
@Autowired private ReservationRepository reservationRepository;
4646

47+
// true story: while testing with abusive-charge-point, from time to time, we get MySql exceptions with
48+
// "Deadlock found when trying to get lock; try restarting transaction" when processing startTransaction and/or
49+
// stopTransaction messages.
50+
// TODO: this is an initial dirty solution/workaround. look into the cause of the problem.
51+
private final Object TRANSACTION_LOCK = new Object();
52+
4753
@Override
4854
public void updateChargebox(UpdateChargeboxParams p) {
4955
ctx.update(CHARGE_BOX)
@@ -170,14 +176,18 @@ public Integer insertTransaction(InsertTransactionParams p) {
170176
// Step 1: Insert transaction
171177
// -------------------------------------------------------------------------
172178

173-
int transactionId = ctx.insertInto(TRANSACTION)
174-
.set(CONNECTOR_STATUS.CONNECTOR_PK, connectorPkQuery)
179+
int transactionId;
180+
181+
synchronized (TRANSACTION_LOCK) {
182+
transactionId = ctx.insertInto(TRANSACTION)
183+
.set(TRANSACTION.CONNECTOR_PK, connectorPkQuery)
175184
.set(TRANSACTION.ID_TAG, p.getIdTag())
176185
.set(TRANSACTION.START_TIMESTAMP, p.getStartTimestamp())
177186
.set(TRANSACTION.START_VALUE, p.getStartMeterValue())
178187
.returning(TRANSACTION.TRANSACTION_PK)
179188
.fetchOne()
180189
.getTransactionPk();
190+
}
181191

182192
if (unknownTagInserted) {
183193
log.warn("The transaction '{}' contains an unknown idTag '{}' which was inserted into DB "
@@ -210,14 +220,16 @@ public void updateTransaction(UpdateTransactionParams p) {
210220
// After update, a DB trigger sets the user.inTransaction field to 0
211221
// -------------------------------------------------------------------------
212222

213-
ctx.update(TRANSACTION)
214-
.set(TRANSACTION.STOP_TIMESTAMP, p.getStopTimestamp())
215-
.set(TRANSACTION.STOP_VALUE, p.getStopMeterValue())
216-
.set(TRANSACTION.STOP_REASON, p.getStopReason())
217-
.where(TRANSACTION.TRANSACTION_PK.equal(p.getTransactionId()))
218-
.and(TRANSACTION.STOP_TIMESTAMP.isNull())
219-
.and(TRANSACTION.STOP_VALUE.isNull())
220-
.execute();
223+
synchronized (TRANSACTION_LOCK) {
224+
ctx.update(TRANSACTION)
225+
.set(TRANSACTION.STOP_TIMESTAMP, p.getStopTimestamp())
226+
.set(TRANSACTION.STOP_VALUE, p.getStopMeterValue())
227+
.set(TRANSACTION.STOP_REASON, p.getStopReason())
228+
.where(TRANSACTION.TRANSACTION_PK.equal(p.getTransactionId()))
229+
.and(TRANSACTION.STOP_TIMESTAMP.isNull())
230+
.and(TRANSACTION.STOP_VALUE.isNull())
231+
.execute();
232+
}
221233

222234
// -------------------------------------------------------------------------
223235
// Step 2: Set connector status back to "Available" again

0 commit comments

Comments
 (0)