2011-09-21 97 views
0

我有一个MySql数据库实例,其中帐户表维护余额字段。我有多个Java应用程序,每个使用Jdbc连接到数据库,这可能会增加或减少字段的值。我如何确保读取,计算和更新值,并且此过程是孤立发生的,并且“知道”可能正在执行同一事情的任何其他Java进程?确保多个Java客户端访问数据库时的数据完整性

+0

这就是为什么RDBMSs首先被发明出来的原因。 – Ingo

回答

5

简单的答案是使用交易: http://dev.mysql.com/doc/refman/5.0/en/commit.html

然而,在你所描述的情况下,我更喜欢不保存的帐户在表中的列的平衡,但通过总结来计算的话与该账户相关的交易的价值。它对你提出的完整性问题不太敏感,而且你不太可能遇到模糊的锁定方案。

+0

在一个已经有1000年交易的长期账户中,你总会总结那些每次都能找到余额的账户吗?或者有什么策略可以避免这种情况,比如维持每年的平衡? –

+2

通常,调整良好的数据库系统并不真正减慢SUM中数百和数十个记录之间的速度。当然,如果你必须计算出数千个账户的余额,那可能不那么容易。在这种情况下,我使用了一种类似于您的建议的策略:有效地归档历史交易,并创建与这些归档交易总和的“期初余额”交易。 –

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块提交或rolback交易,否则你可能在你的数据库死锁结束。

编辑:如果您的Java应用程序是最终用户客户端,则用户总是有风险,即用户直接连接到数据库(例如使用Access)绕过您的事务管理逻辑。这是我们开始在两者之间放置应用程序服务器的原因之一。解决方案也可能是实现存储过程,以便客户端根本不与表进行交互。

1

如果您使用的是InnoDB引擎,那么您可以使用MySQL record level locking锁定来自其他客户端的更新的特定帐户记录。

更新:替代地,您可以应用程序级锁描述为here

+0

从参考手册 - '死锁可能...'和'一般来说,表锁优于行级锁' - 不会激发信心。您是否使用了行级锁定,并且使用起来很简单?你有没有关于如何使用Jdbc执行“锁定”的示例代码?谢谢。 –

相关问题