バネブック、スプリングデータ、およびmysqlを使用してトランザクションを理解しようとしています。バネデータとmysqlを使って2トランザクションメソッドを実行するとデッドロックが発生する
データベースのレコードを更新するために使用されるサービスUpdateServiceを作成しました。メソッドchangeとchange2はトランザクションで実行されます。
@Autowired
private UserRepo userRepo;
@Transactional(isolation = Isolation.SERIALIZABLE)
public void change() {
User user = userRepo.findOne("Jan");
write("before change", user);
sleep(2000);
user.setPassword("new password");
write("after change", user);
}
@Transactional(isolation = Isolation.SERIALIZABLE)
public void change2() {
User user = userRepo.findOne("Jan");
write("before change2", user);
user.setSecondName("new name");
write("after change2", user);
}
とするとき、私は私がログを受信した変更とCHANGE2メソッドを呼び出します。
before change User(name=Jan, secondName=Adam, password=Kowalski)
before change2 User(name=Jan, secondName=Adam, password=Kowalski)
after change2 User(name=Jan, secondName=new name, password=Kowalski)
after change User(name=Jan, secondName=Adam, password=new password)
その後も、私は例外が発生しました:
com.mysql.jdbc.exceptions.jdbc4.MySQLTransactionRollbackException: Deadlock found when trying to get lock; try restarting transaction
取引CHANGE2は、変更前の始まり、なぜ私の質問があります終わらせる?デッドロックの理由は何ですか?
文脈をもっと与えてください。すなわち、 'change'と' change2'はどのように実行されますか?それらは同時に実行されますか? –
これらはコントローラの形で実行されます @RequestMapping( "/ change") private void change(){ updateService.change(); } change2は類似しています 私は郵便配達の変更と即座に変更2を実行します(これは2秒目に最初のトランザクションが終了するのを防ぐために2秒間スリープ状態を追加した理由です) – adrian215
あなたのコードでは、 'change2'は' change'がトランザクションを終了した後にのみ開始します。 'findOne'メソッドは' SHARE MODE'でselectを実行します。これは同時読み込みを許可します。私が理解できないことはデッドロックです。 –