SQL求和表达式和锁

SQL求和表达式和锁,sql,database,postgresql,database-concurrency,Sql,Database,Postgresql,Database Concurrency,我对正确的SQL解决方案有问题 当前情况: 我的数据库包含带有银行交易记录(贷记和借记)的表 信用交易记录被签署为积极金额(+),并且 借方交易记录为负金额(-) 使用DB的应用程序是一个多用户webapp,所以事务表包含许多行,这些行引用不同的用户。 一些webapp操作需要使用交易表和保存借记交易(操作价格)检查已登录用户的实际余额 我考虑了这个机制的架构,并提出了一些问题: 每次用户请求时,将余额计算为交易贷项和借项的总和是一个好主意吗?我知道这对db来说可能效率很低。也许我应该在某处

我对正确的SQL解决方案有问题

当前情况: 我的数据库包含带有银行交易记录(贷记和借记)的表

  • 信用交易记录被签署为积极金额(+),并且
  • 借方交易记录为负金额(-)
使用DB的应用程序是一个多用户webapp,所以事务表包含许多行,这些行引用不同的用户。 一些webapp操作需要使用交易表和保存借记交易(操作价格)检查已登录用户的实际余额

我考虑了这个机制的架构,并提出了一些问题:

  • 每次用户请求时,将余额计算为交易贷项和借项的总和是一个好主意吗?我知道这对db来说可能效率很低。也许我应该在某处保存快照

  • 当一个用户将“余额”检查为贷记/借记交易的总和,而另一个用户同时保存借记交易(因为他/她更快)时,如何确保数据聚合?我想一个悲观的锁,但我应该锁什么?我知道在Postgresql(我使用的数据库)上可能不可能使用聚合锁(SUM)。”


  • 对不起,对于我的英语,我希望我的问题是可以理解的。 在账户记录中存储余额,以及余额的准确日期

    获取当前余额就是读取账户余额,然后包括自该日期起的所有交易

    您可以有一个重新计算的计划作业,时间戳在午夜后一小时平衡

    或者(这是我的首选解决方案):

    每次加载交易或交易批时,锁定相关的帐户记录,并将插入的值作为同一交易的一部分进行更新


    这样做的好处是可以序列化对帐户的访问,这有助于确定交易是否可以继续进行,因为这是基于余额计算的决定。

    如果您希望避免在用户帐户上保留余额,这可能会有更好的性能,我将尝试的方法是d是:

    • 每笔交易只与一个账户相关
    • 每笔交易都会有该笔交易后的账户余额
    因此,该账户的最后一笔交易将具有当前余额

    例:


    通过这种方式,您将能够获得帐户余额(具有该帐户ID的最后一笔交易),并能够更好地查看余额随时间的变化。

    谢谢。因此,按日期时间对交易进行排序(对于给定的帐户ID)是一个好主意吗,然后获取最后一个事务,然后在执行时锁定它:检查余额并保存另一个事务?我的TransactionId主键是UUID,因此我无法按它排序。Datetime精度如何?例如,当几个事务具有相同的Datetime时(DD/MM/YYYY HH:MM:ss.SSS)-可能吗?@user6492999 1)您应该锁定它。当您插入新事务时,您要确保您选择的是最后一个事务的余额。如果您期望高流量,请确保阅读有关数据库事务的信息,以优化操作并避免死锁。@user6492999 2)我认为精度非常高,但n尽管我会测试两个连续插入是否可能具有相同的datetime,但这可能会导致不一致。datetime精度可以在数据库引擎文档中找到。对于Postgresql,您可以在此处找到最新版本(9.6):
    TransactionId | AccountId | Datetime | Ammount | Balance 
                1 |         1 | 7/11/16  |       0 |       0 
                2 |         1 | 7/11/16  |     500 |     500 
                3 |         1 | 7/11/16  |     -20 |     480 
                4 |         1 | 8/11/16  |      50 |     530 
                5 |         1 | 8/11/16  |    -200 |     330