数据库保证在并发情况下不会发生死锁,而且还能保证ACID
Connection conn = null; try{ // 获取数据库连接 conn = DriverManager.getConnection(); // 设置手动提交事务 conn.setAutoCommit(false); // 执行转账SQL ... // 提交事务 conn.commit(); } catch (Exception e) { // 出现异常回滚事务 conn.rollback(); }
@AllArgsConstructor public class UnsafeAccount { private long balance; // 转账,存在死锁问题 public void transfer(UnsafeAccount to, long amt) { synchronized (this) { synchronized (to) { if (this.balance > amt) { this.balance -= amt; to.balance += amt; } } } } }
Java语言并不支持STM,可以借助第三方类库来Multiverse实现
public class Account { // 余额 private TxnLong balance; public Account(long balance) { this.balance = StmUtils.newTxnLong(balance); } // 转账 public void transfer(Account to, int amt) { // 原子化操作 StmUtils.atomic(() -> { if (this.balance.get() > amt) { this.balance.decrement(amt); to.balance.increment(amt); } }); } }