我有一个带有帐户表的MySql数据库实例,该表维护余额字段。我有多个Java应用程序,每个都使用Jdbc连接到数据库,可能会增加或减少 Balance 字段的值。如何确保读取,计算和更新 Balance 值并确保此过程独立发生,并且“了解”可能正在执行相同操作的任何其他Java进程?
答案 0 :(得分:5)
简单的答案是使用交易: http://dev.mysql.com/doc/refman/5.0/en/commit.html
但是,在您描述的情况下,我更倾向于不将帐户的余额存储为表格中的列,而是通过将与该帐户相关的交易的价值相加来计算它。它对您提出的完整性问题的敏感程度要低得多,而且您不太可能遇到模糊的锁定方案。
答案 1 :(得分:2)
一种简单的方法是JDBC事务管理。请参阅java.sql.Connection.setAutoCommit()
文档。它使您能够显式禁用自动语句提交:
Connection c = /* retrieve connection */
c.setAutoCommit(false);
c.setTransactionIsolation(/* depends on your requirements */);
c.executeQuery(/* */);
c.executeUpdate(/* */);
c.commit(); /* or c.rollback() */
在实际情况中,您必须引入finally
块来提交或回滚事务,否则您最终可能会在数据库中出现死锁。
编辑:如果您的Java应用程序是最终用户客户端,那么用户可能会直接连接到数据库(例如使用Access)绕过您的事务管理逻辑。这是我们开始在其间放置应用程序服务器的一个原因。解决方案也可能是实现存储过程,以便客户端根本不与表交互。
答案 2 :(得分:1)
如果您使用InnoDB引擎,则可以使用MySQL record level locking锁定特定帐户记录以获取其他客户端的更新。
更新:或者,您可以使用here描述的应用级锁定。