【问题标题】:Spring Transaction roll back both `UPDATE` and `INSERT`Spring Transaction 回滚 `UPDATE` 和 `INSERT`
【发布时间】:2019-07-27 00:26:09
【问题描述】:
@Service
@Transactional
public class OrderService {

  //Implemented with JdbcTemplate (no ORM)
  //Both Dao use the same DataSource
  private AccountDao accountDao;
  private OrderDao orderDao;

public void update(int accountId){

  //Get account and do some calculation (simplifed version here)
  Account account = accountDao.findByid(accountId)
  int newAmount = account.getAmoount * 100;

  //Update account table 
  accountDao.updateAmount(accountId, newAmount);

  //Insert new order
  Order order = ....
  orderDao.save(order);

}

}

在上面的代码中,如果更新的帐户行被另一个事务修改,我想回滚accountDao.updateAmountorderDao.save

【问题讨论】:

    标签: java sql spring jdbc transactions


    【解决方案1】:

    您需要手动实现乐观锁定。

    为每个表添加 VERSION 列。

    当你加载和实体..你需要加载当前版本

    当您更新实体时,您必须在 where 子句中添加版本检查并在执行后获取更新的行数 (int rowCount = st.executeUpdate();)

    示例:UPDATE ACCOUNT set AMOUNT = x, VERSION = VERSION+1 where ID = XX and VERSION = CURRENT_VERSION

    如果更新的行数为 1,则表示该行已被另一个事务(UPDATE 或 DELETE)修改

    【讨论】:

    • 我使用SELECT FOR UPDATE 解决了这个问题。但是,FOR UPDATE 不适用于聚合子句...
    • 你使用了悲观锁定,它可以工作,但它有一些缺点:性能,如果不小心使用会出现死锁,如果正在运行的事务很慢,则会在等待事务中锁定超时
    猜你喜欢
    • 1970-01-01
    • 2018-09-15
    • 2019-06-29
    • 2018-11-13
    • 2017-07-22
    • 2017-03-27
    • 2013-05-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多