当您在多线程环境中收到同一字段的并发插入和更新时,是否有办法解决问题。
示例
线程1
boost::multi_array<std::complex<double>, 3> SAP_max_combined_complex(boost::extents[1][1][1], boost::fortran_storage_order());
// Later in the code
SAP_max_combined_complex.resize(boost::extents[xDim][yDim][zDim]);
// The multi_array is populated correctly - this has been verified
mwSize numDims = SAP_max_combined_complex.num_dimensions();
mwSize outputSizes[3] = {SAP_max_combined_complex.shape()[0], SAP_max_combined_complex.shape()[1], SAP_max_combined_complex.shape()[2]};
mxArray* outputData = mxCreateNumericArray(numDims, outputSizes, mxDOUBLE_CLASS, mxCOMPLEX);
memcpy(mxGetData(outputData), (void*) SAP_max_combined_complex.data(), (sizeof(std::complex<double>) * SAP_max_combined_complex.num_elements()));
// I then write the mxArray to the file with
matPutVariable(mpMatFile, fieldName.toStdString().c_str(), outputData);
线程2
BEGIN
insert into users (name,age) values('spiderman',27)
COMMIT
大部分时间更新(事务)都不知道插入发生因此它会抛出错误。
我在这里看到的是竞赛条件的经典例子,避免竞争条件的一种方法是使用效果锁。
如何对尚未存在于DB中的记录应用锁(记录)。
在上面的insert语句示例中,以便Update知道该记录不在DB中。
答案 0 :(得分:0)
基于锁定的解决方案非常困难,可能不值得。您必须找到一种方法来创建一组数据,其中包含所有可能的名称&#39;字段,然后围绕该数据创建一个咨询锁定系统。它也可能容易出错。
但是,如果问题确实是UPDATE
在INSERT
之后仍然有效,那么就会有更简单的解决方案。
具体来说,我想到的是:
BEGIN;
SELECT count(*) FROM users WHERE name = 'spiderman';
-- on the application side, check to see what the result is
-- if it's 0, ROLLBACK
-- if it's >0:
UPDATE users SET age = 26 WHERE name = 'spiderman';
COMMIT;
如果你最终回滚,你会回来再试一次,这是否意味着像sleep
这样简单的事情10秒并重新尝试,或者更复杂的事情就像将工作项放回队列并继续进行不同的工作。
如果您担心SELECT
和UPDATE
之间发生的更新,可以SELECT FOR UPDATE
,这将锁定所选行,直到您的交易完成为止。