Rumah  >  Artikel  >  Java  >  Bagaimana untuk menyelesaikan masalah menggunakan SpringBoot secara tidak segerak dengan transaksi

Bagaimana untuk menyelesaikan masalah menggunakan SpringBoot secara tidak segerak dengan transaksi

WBOY
WBOYke hadapan
2023-05-27 14:37:241238semak imbas

Senario terbaru yang dihadapi ialah dalam kaedah A yang dianotasi dengan @Transactional, kaedah B yang ditandakan dengan anotasi @Async telah dipanggil Memandangkan urus niaga kaedah A tidak dilakukan apabila kaedah B dilaksanakan, kaedah B tidak dilakukan Semasa proses pelaksanaan, data yang belum diserahkan dalam kaedah A tidak boleh diperoleh, jadi pada akhirnya, kaedah B dilaksanakan secara tidak normal.

@Transactional
public void create(User user){
  // 如果用户已存在,则先删除
  delete(user.id);
  // 创建用户
  int userId = insert(user);
  //  更新用户信息
  update(userId);
}
@Async
public void update(Integer userId){
  Icon icon = getUserIcon(userId);
  // 更新用户图片
  updateUserPohot(userId,icon);
}

Seperti kod di atas, saya menandai anotasi transaksi @Transactional pada kaedah mencipta pengguna, dan kemudian memanggil kaedah kemas kini kemas kini() di dalamnya. Kaedah ini ditandakan dengan anotasi @Async. Walaupun kod itu nampaknya tidak mempunyai masalah, apabila kaedah kemas kini() sebenarnya dilaksanakan, kerana ia dilaksanakan oleh utas lain, ada kemungkinan transaksi yang sepadan dengan kaedah create() belum diserahkan lagi, dan kemas kini( ) kaedah tidak dapat membacanya Rekod pengguna yang baru dimasukkan diperoleh, menyebabkan kemas kini gagal.

Penyelesaian

Laraskan logik untuk memastikan transaksi dilakukan sebelum memanggil kaedah tak segerak

Punca masalah ini adalah disebabkan oleh penggunaan @Transactional dan @Async anotasi bersama-sama, kemudian Kita boleh bermula dari arah ini Mula-mula, kita boleh mengesahkan bahawa transaksi kaedah create() diserahkan, dan kemudian laksanakan kaedah kemas kini tak segerak:

public void create(User user){
  int userId = doCreate(user);
  //  更新用户信息
  update(userId);
}
@Transactional
public void doCreate(User user){
    // 如果用户已存在,则先删除
  delete(user.id);
  // 创建用户
  return insert(user);
}
@Async
public void update(Integer userId){
  Icon icon = getUserIcon(userId);
  // 更新用户图片
  updateUserPohot(userId,icon);
}

Kaedah tak segerak dipanggil di luar kaedah transaksi, supaya kaedah tak segerak adalah Data transaksi yang komited boleh dibaca.

Kami boleh menggunakan TransactionTemplate untuk menggantikan anotasi @Transactional

@Autowired
TransactionTemplate transactionTemplate;
public void create(User user){
  int userId = transactionTemplate.execute(status->{
    // 如果用户已存在,则先删除
    delete(user.id);
    // 创建用户
    return insert(user);
  });
  //  更新用户信息
  update(userId);
}
@Async
public void update(Integer userId){
  Icon icon = getUserIcon(userId);
  // 更新用户图片
  updateUserPohot(userId,icon);
}

Dengan menggunakan TransactionTemplate untuk membahagikan butiran transaksi, pastikan transaksi telah dilakukan sebelum memanggil kaedah tak segerak.

Penyelesaian di atas pada asasnya boleh menyelesaikan masalah berikut adalah penyelesaian yang diberikan oleh spring yang terdapat di Internet:

@Transactional
public void create(User user){
  // 如果用户已存在,则先删除
  delete(user.id);
  // 创建用户
  int userId = insert(user);
  TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
    @Override
    public void afterCommit() {
      //  更新用户信息
      update(userId);
    }
  });
}
@Async
public void update(Integer userId){
  Icon icon = getUserIcon(userId);
  // 更新用户图片
  updateUserPohot(userId,icon);
}

Dengan mendaftarkan kaedah tak segerak sebagai operasi selepas penyerahan transaksi, Spring It boleh. secara automatik membantu kami melaksanakan operasi yang sepadan selepas transaksi diserahkan.

Atas ialah kandungan terperinci Bagaimana untuk menyelesaikan masalah menggunakan SpringBoot secara tidak segerak dengan transaksi. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Artikel ini dikembalikan pada:yisu.com. Jika ada pelanggaran, sila hubungi admin@php.cn Padam