我创建了两个(或更多)线程来在数据库中的表中插入数据。插入时,有一个字段CreatedDateTime
,当然,它存储记录创建的日期时间。
对于一种情况,我希望线程保持同步,以便它们的CreatedDateTime
字段具有完全相同的值。使用多线程测试时,通常我有不同的毫秒......
我想在我的系统中测试不同的场景,例如:
我可能还没有列出其他测试用例。
答案 0 :(得分:5)
是的,这就是发生的事情。即使是一些自然界的怪物,你的线程也会在同一时间开始,它们很快就会因为它们之间的资源争用而失败(至少可以访问数据库表或DBMS服务器进程)。
如果它们大部分保持步调(即从不超过几毫秒),只需为CreatedDateTime字段选择不同的“分辨率”。将它放入最接近的10 th 秒(或秒)而不是毫秒。或者以其他方式使用固定值。
否则,只要意识到这是完全正常的行为。
而且,正如BC在评论中指出的那样,你可能会误解“同步”一词的用法。它(在Java中,我希望C#类似)用于确保两个线程不会同时访问同一个资源。实际上,它几乎可以保证线程不会保持同步,因为您理解术语的意思(我个人认为您的定义在英语使用方面是正确的(同时发生的事情),但是某些计算机语言已经定义了他们自己的目的)。
如果您正在测试特定时间戳进入数据库时会发生什么,那么您不能依赖于按特定顺序和特定时间安排的线程“表现自己”。你真的需要以某种方式虚拟数据,否则就像试图将果冻钉在树上(或训练一只猫)。
一种解决方案是不使用诸如getCurrentTime()
或now()
之类的内容,而是使用具有已知时间戳的特定插入集。根据您的实际架构,这可能很困难(例如,如果您只是调用一个API,它本身的时间戳会达到毫秒分辨率)。
如果您控制填充时间戳列的实际SQL,则需要将其更改为使用预先计算的值而不是now()
或其等效值。
答案 1 :(得分:0)
如果要在插入的多行上使用相同的时间戳;你应该创建一个SQL线程,它将在一个查询中执行多行插入,这将允许您获得相同的时间戳。除此之外,我同意其他人的意见,除非您在应用程序中看到时间戳并分享要插入的时间戳,否则无法在多线程的巨大分辨率下获得准确的时间戳。当然,这会抛出窗外的线索问题。这就像说,我将分享这些数据,但我不想使用互斥锁,因为它们会在遇到锁定()时阻止其他线程进行处理。