Ruby on rails Rails线程测试db锁
假设我们要测试数据库是否被锁定Ruby on rails Rails线程测试db锁,ruby-on-rails,ruby,multithreading,Ruby On Rails,Ruby,Multithreading,假设我们要测试数据库是否被锁定 $transaction = Thread.new { Rails.logger.debug 'transaction process start' Inventory.transaction do inventory.lock! Thread.stop inventory.units_available=99 inventory.save end } $race_condition
$transaction = Thread.new {
Rails.logger.debug 'transaction process start'
Inventory.transaction do
inventory.lock!
Thread.stop
inventory.units_available=99
inventory.save
end
}
$race_condition = Thread.new {
Rails.logger.debug 'race_condition process start'
config = ActiveRecord::Base.configurations[Rails.env].symbolize_keys
config[:flags] = 65536 | 131072 | Mysql2::Client::FOUND_ROWS
begin
connection = Mysql2::Client.new(config)
$transaction.run
$transaction.join
rescue NoMethodError
ensure
connection.close if connection
end
}
Rails.logger.debug 'main process start'
$transaction.join
Rails.logger.debug 'main process after transaction.join'
sleep 0.1 while $transaction.status!='sleep'
Rails.logger.debug 'main process after sleep'
$race_condition.join
Rails.logger.debug 'main process after race_condition.join'
理论上,我认为它将执行事务线程,然后等待(thread.stop),然后主进程将看到它正在休眠,并启动竞争条件线程(当它实际工作时,它将尝试更改锁定表中的数据)。然后,竞争条件将在完成后继续事务线程
奇怪的是痕迹
main process start
transaction process start
race_condition process start
从nodejs来看,线程似乎并不完全是用户友好的。。不过,必须有办法做到这一点
是否有一种更简单的方法来锁定数据库,然后尝试使用不同的线程对其进行更改?对于任何要使其成为“互斥”的资源,您需要使用互斥对象类,并使用同步方法在一个线程使用资源时将其锁定。你必须这样做:
semaphore=Mutex.new
并在线程实例中使用它
$transaction = Thread.new {
semaphore.synchronize{
# Do whatever you want with the *your shared resource*
}
}
这样可以防止任何死锁
希望这有帮助 Thread.new自动启动线程。 但这并不意味着它正在执行。 这取决于操作系统、ruby或jruby、内核数量等 在您的示例中,主线程运行到 $transaction.join, 只有到那时,您的事务线程才会启动,只是碰巧而已。 它仍然运行Thread.stop,然后您的“$race\u condition”线程启动,因为其他两个线程都被阻塞(它可能以前启动过) 这就解释了你的日志 您有两个$transaction。加入
他们一直等到线程退出,但是一个线程只能退出一次。。。 我不知道接下来会发生什么,也许第二个电话会一直等下去
对于您的测试,需要某种类型的显式同步,以便当事务处理线程位于事务中间时,我们的RraceX线程精确写入。您可以使用互斥来实现这一点,但最好是某种消息传递。以下博客文章可能会有所帮助:
查看我的答案,如果有帮助,请打分!干杯:)