数据库
首页 > 数据库> > MySQL事务:多个并发事务和数据完整性

MySQL事务:多个并发事务和数据完整性

作者:互联网

我在一个相当复杂的Web应用程序中使用事务来管理几个MySQL InnoDB表中的数据.简而言之,给定的交易如下:

>从“user_point_totals”表中的行读取数据
>各种阴谋计算用户的新点总数应该是多少
>在“user_point_totals”表中创建一个新条目,反映更新的总数

假设用户A执行一些具有与点相关的分支的动作,执行步骤1,该执行线程将用户的总点数读入内存,并且应用程序开始计算新的总计.同时,用户B执行对用户A的总分有影响的动作,并开始另一个交易;但是,第一个事务尚未完成,因此第二个线程获得与第一个事务(来自同一个表行)相同的点总值作为起始点.随后,事务1完成并创建新的用户点总数,其中感知新值应该是什么,并且此后不久,事务2完成并且还为用户的点总数创建新行.但是,第二个事务的点总数现在不正确,因为它无法考虑事务1创建的新总数.

我的问题是:

>由于交易的原子性质,这种情况是不可能的,我显然不理解我应该这样做?
>如果没有,如何确保在这些情况下存在数据完整性?

谢谢你的考虑!

解决方法:

在技​​术层面,您可以使用MySQL的table-locking(或行锁定)功能.这将允许您检测是否有人正在使用该表计算某些东西.另一方面,这种技术需要考虑许多因素,例如进程崩溃等情况.

但是,在实际层面上,我怀疑你是否愿意做这样的事情.
MySQL中的sum()或avg()等运算符已针对此需求进行了优化.如果您需要做的是对表的某些列求和并在表中得到答案,您可以使用视图或创建临时表(可能但更慢).您不应该有一个包含可以从其他列计算的值的列.这种情况导致不协调,因为如果关系不平衡则不清楚哪个字段是真的. (它是输入脚本错误还是某些程序员故意重用该字段?)

在第二个注释中,确保在MySQL实例上使用InnoDB表,否则您的系统将不会完全ACID编译,这意味着您将无法获得所需的原子性.

标签:mysql,database,transactions,data-integrity
来源: https://codeday.me/bug/20190630/1341585.html