异步SQL操作

7
我有一个问题,不确定如何最好地解决。
我有一个应用程序,它根据即席请求更新数据库。其中一个请求非常常见。该请求本身很简单,但具有一些复杂的前提条件。
对于此请求,业务层首先从数据层请求一组数据。业务逻辑层评估来自数据库和请求的参数的数据,从中确定要执行的操作,并创建请求的响应消息。然后,业务层现在执行实际的更新命令,这是请求的目的。
这最后一步是问题所在,该命令取决于数据库的状态,因为数据库的状态可能已经发生了变化。在几次往返到数据库中锁定此操作中读取的数据似乎也不是一个好主意。是否有“最佳实践”方法来完成这样的事情呢?谢谢!
4个回答

2

简单来说,当你执行更新命令时,你担心数据库可能已经发生了改变?

那么就调用那些有防御性编写的存储过程,只有在被调用时数据处于可接受的状态时才会进行更新(通过检查外键引用、数据完整性等)。

如果需要,我可以帮助模拟其中的某些方面。


是的,但这会将业务逻辑(我希望能够轻松更改)放在存储过程中。 - Paul
1
@Paul,如果存储过程仅用于检查数据是否已更改,则不需要。我认为,如果您在BL中执行的所有操作都是检查条件以确定正确的表/列更新,那么这些操作应该放在存储过程中。 - AllenG
检查引用完整性和外键是否OK是最佳实践,通过结构和元数据隐式支持业务逻辑(而不是通过人为的过程代码显式支持)也是良好的实践。 - amelvin

2
你可以存储修改后的业务对象的原始状态,并将原始对象与其数据库对应物进行比较,以检查是否有任何更改。
如果已经进行了更改,则您可以选择基于原始、修改和存储(数据库)对象合并对象,或者取消更新并告诉客户端更新失败。

1
以下是一些谷歌关键词:上述策略也被称为“乐观并发控制”,在更复杂的实现中,我们还谈到了“编排”、“业务流程管理”和“补偿事务”,另请参见“sagas”。另一种选择是在开始事务时锁定数据(整个数据库或仅限于您所涉及/查看的部分,完全锁定或仅写入锁定),并让每个人等待操作完成 - 这就是所谓的“悲观并发控制”的基础。 - ddimitrov

0

这有点困难,因为问题中没有太多具体信息,所以我将给出一个简单的例子,您可能可以将其应用到您的情况中。

加载所有数据以及最后更改日期(yyyy-mm-dd hh:mi:ss.mmm)

SELECT AAA,BBB,LastChgDate FROM YourTable WHERE ID=xxxxxx

执行你的业务逻辑

保存数据

UPDATE YourTable SET AAA=aaaaa,BBB=bbbbb WHERE ID=xxxxxx AND LastChgDate=zzzzzz

如果行数不等于1,则出现错误,表示其他人已更改数据,否则保存数据。

这种模式被称为乐观并发控制:http://en.wikipedia.org/wiki/Optimistic_concurrency_control - Steve Schnepp

0

使用适当的事务隔离模式,并在单个数据库事务中执行所有操作(即在步骤1中开始事务,然后在步骤3之后提交)。

您的问题有点含糊不清,但我猜测您需要快照或读取已提交的模式。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接