确保多个java客户端访问数据库时的数据完整性

确保多个java客户端访问数据库时的数据完整性,java,mysql,database,jdbc,data-integrity,Java,Mysql,Database,Jdbc,Data Integrity,我有一个MySql数据库实例,其中有一个Account表,它维护一个Balance字段。我有多个Java应用程序,每个应用程序都使用Jdbc连接到数据库,这可能会增加或减少Balance字段的值。如何确保平衡值被读取、计算和更新,并且这个过程是孤立发生的,并且对任何可能在做同一件事情的java进程中都“知道”? < P>一个简单的方法是JDCS事务管理。见文件。它使您能够显式禁用自动语句提交: Connection c = /* retrieve connection */ c.setAutoC

我有一个MySql数据库实例,其中有一个Account表,它维护一个Balance字段。我有多个Java应用程序,每个应用程序都使用Jdbc连接到数据库,这可能会增加或减少Balance字段的值。如何确保平衡值被读取、计算和更新,并且这个过程是孤立发生的,并且对任何可能在做同一件事情的java进程中都“知道”?

< P>一个简单的方法是JDCS事务管理。见文件。它使您能够显式禁用自动语句提交:

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)的风险。这就是我们开始将应用服务器置于两者之间的原因之一。解决方案还可以是实现一个存储过程,这样客户机根本就不会与表交互。

一个简单的方法是JDBCs事务管理。见文件。它使您能够显式禁用自动语句提交:

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)的风险。这就是我们开始将应用服务器置于两者之间的原因之一。解决方案还可以是实现一个存储过程,这样客户机根本不会与表交互。

简单的答案是使用事务:


然而,在您描述的情况下,我更倾向于不将账户余额存储为表中的列,而是通过将与该账户相关的交易的价值相加来计算它。它对您提出的完整性问题不太敏感,并且您不太可能遇到模糊的锁定场景

简单的答案是使用事务:


然而,在您描述的情况下,我更倾向于不将账户余额存储为表中的列,而是通过将与该账户相关的交易的价值相加来计算它。它对您提出的完整性问题不太敏感,并且您不太可能遇到模糊的锁定场景

如果您使用的是InnoDB引擎,则可以使用锁定特定帐户记录,以便从其他客户端进行更新


更新:您也可以使用所述的应用程序级锁。

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


更新:您也可以选择描述的应用程序级锁。

在一个拥有1000笔交易的长期账户中,您是否每次都会将这些交易相加以找到余额?或者有什么策略可以避免这种情况,比如保持每年的平衡?一般来说,一个经过良好调优的数据库系统并不会在一个总数中的数百到(上万)条记录之间明显减速。当然,如果你必须计算出数千个账户的余额,那可能就不那么容易了。在这种情况下,我使用了与您建议的类似的策略:有效地归档历史交易,并使用这些归档交易的总和创建一个“期初余额”交易。在一个拥有1000笔交易的长期账户中,您每次都会将这些交易相加以找到余额吗?或者有什么策略可以避免这种情况,比如保持每年的平衡?一般来说,一个经过良好调优的数据库系统并不会在一个总数中的数百到(上万)条记录之间明显减速。当然,如果你必须计算出数千个账户的余额,那可能就不那么容易了。在这种情况下,我使用了一种类似于您建议的策略:有效地归档历史事务,并使用这些归档事务的总和创建“期初余额”事务。参考手册中的“死锁是可能的…”和“通常情况下,表锁优于行级锁”并不能激发信心。您是否使用了行级锁定,它是否易于有效使用?您是否有任何关于如何使用Jdbc预执行“锁”的示例代码?谢谢。参考手册中的“死锁是可能的…”和“通常,表锁优于行级锁”并不能激发信心。您是否使用了行级锁定,它是否易于有效使用?您是否有任何关于如何使用Jdbc预执行“锁”的示例代码?谢谢。这就是为什么RDBMS首先被发明的原因。这就是为什么RDBMS首先被发明的原因。