私は、エンティティを更新する必要がありますが、それは本当にSpring + Hibernate - トランザクションが実際にコミットされたとき?
私の方法は
@Override
@Transactional(isolation = Isolation.SERIALIZABLE)
public void lightOn(int idInterruttore) {
Interruttore interruttore = dao.findById(idInterruttore);
String inputPin = interruttore.getInputPin();
String pinName = interruttore.getRelePin();
GpioController gpio = interruttore.getGpio();
GpioPinDigitalOutput rele = gpio.provisionDigitalOutputPin(RaspiPin.getPinByName(pinName));
try {
DateTime date = new DateTime();
Date now = date.toDate();
int i = 1;
while (getInput(inputPin, gpio) != 1) {
if(i > 1){
logger.debug(String.format("Try n %s", i));
}
pushButton(rele);
Thread.sleep(1000);
i++;
}
dao.updateInterruttore(idInterruttore, now, true);
} catch (GpioPinExistsException | InterruptedException gpe) {
logger.error("GPIO già esistente", gpe);
} finally {
gpio.unprovisionPin(rele);
}
logger.debug(String.format("After the update status should be true and it's %s",
interruttore.isStato()));
}
updateInterruttoreがあるが更新されたとき、私は知らない...
を特異な問題に直面しています(私はこのフォームを使用して、更新後にコミットを呼び出すようにしました...このメソッドに複数の呼び出しを行うことができますが、最初のものだけを更新する必要があるため、ロックオプションがあります。
@Override
public void updateInterruttore(int idInterruttore, Date dateTime, boolean stato) {
Session session = getSession();
Transaction tx = session.beginTransaction();
String update = "update Interruttore i set i.dateTime = :dateTime, i.stato = :stato where idInterruttore = :idInterruttore";
session.createQuery(update).setTimestamp("dateTime", dateTime).setBoolean("stato", stato)
.setInteger("idInterruttore", idInterruttore).setLockOptions(LockOptions.UPGRADE).executeUpdate();
tx.commit();
}
}
はまあ...私は、ログを更新したときに私を言う:
After the update status should be true and it's false
これは私がメソッドを呼び出すだけで最初の時間に発生し、二度目interruttore.isStatoが正しく真実です。
これはどうしてですか?
私の問題は、メソッドへの複数の同時呼び出しがありますが、最初の1つだけが 'pushButton(rele)'コールを呼び出してInterruttoreを更新しなければならないため、他の人は 'interruttore.isStato () 'を呼び出し、press関数を呼び出さないでください。私はいくつかの試みを行い、このようにして(多かれ少なかれ)それが働いていることがわかりました。私はSpringの '@ Transactional'indeedを使用していますが、通常はセッターのメソッドを使用してエンティティを更新します。 – besmart
DB並行処理とビジネス同時性を混在させているようです。トランザクションの途中でThread.sleepを呼び出しているという事実は本当に悪い兆候です。 HibernateセッションとDBとのやりとりにほとんど時間を費やさずにコードを再設計し、アプリケーションの並行性を他の場所で管理する必要があります。 DBの並行性は、トランザクションではなくユーザに基づいています。 – raminr