我有并发应用程序,需要将递增/递减(余额变更)更新到帐户表中的余额列。
我正在使用Oracle Toplink。 执行并发更新的一种方法是使用版本列来使用乐观锁定。
1)乐观锁定
更新帐户设置余额=?,版本=?其中id =?和版本=?
2)原子更新
更新帐户设置余额=余额+?其中id =?
我想使用2)选项,因为它更容易,并且在更新之前不需要我首先读取值(如1))。
SQLCall sc = new SQLCall("update account set balance=balance + #delta where id=#id");
DataModifyQuery data = new DataModifyQuery(sc);
data.addArgument("delta", BigDecimal.class);
data.addArgument("id", Long.class);
Vector param = new Vector(2);
param.add(new BigDecimal(.01));
param.add(new Long(12345));
getSession().executeQuery(data, param);
我在执行更新查询时遇到问题。问题是它没有反映最后的金额。
是2)选项是否真的更新了原子?
我是否遵循正确的编码方法。这个例子有什么问题吗?
请指导
答案 0 :(得分:0)
您的原子更新不是原子的。
如果多个交易同时进行,两者都会增加他们自己对当前余额的看法,最后一个将获胜。实际上,交易是彼此隔离的(即我在 ACID 中),并且看不到其他交易所做的更改。
你仍然需要锁定(乐观或悲观)来正确地做到这一点。