require 'thread'
require 'benchmark'
require 'rubygems'

DB_NAME = "SOME_DB_NAME"
DB_CONFIG = {
  :username => 'root',
  :password => '',
  :host => '127.0.0.1',
  :db => DB_NAME,
  :adapter  => 'jdbc',
  :driver   => 'com.mysql.jdbc.Driver',
}

if ENV["data_mapper"]
  puts "Loading DataMapper"
  gem 'dm-core'
  require 'dm-core'
  #load the right drivers
  DataMapper.setup(:default, "mysql://localhost:3306/#{DB_NAME}")
elsif RUBY_PLATFORM =~ /java/
  puts "Loading JDBC-MySQL"
  gem "jdbc-mysql"
  #make sure to load the class
  Java::com.mysql.jdbc.Driver
else
  puts "Loading MRI MySQL"
  gem 'mysql'
  require 'mysql'
end

def execute_query
  sql_statement = "select sleep(1) from dual" 
  puts "  thread: #{Thread.current} executing: #{sql_statement}"
  if ENV["data_mapper"]
    conn = DataObjects::Connection.new("mysql://localhost:3306/#{DB_NAME}")
    cmd = conn.create_command(sql_statement)
    cmd.execute_reader
    conn.dispose
  elsif RUBY_PLATFORM =~ /java/
    conn = java.sql.DriverManager.get_connection("jdbc:mysql://localhost:3306/#{DB_NAME}", DB_CONFIG[:username], DB_CONFIG[:password])
    stmt = conn.create_statement
    rs = stmt.execute_query(sql_statement)
    rs.close
    stmt.close
    conn.close
  else  
    conn = Mysql.new(DB_CONFIG[:host], DB_CONFIG[:username], DB_CONFIG[:password], DB_NAME, 3306, nil, nil)
    res = conn.query(sql_statement)
    res.free
    conn.close
  end
end

ITERATIONS = 4
puts "Serial: Testing #{ITERATIONS} iterations"
puts "Serial: " + Benchmark.measure {  ITERATIONS.times {execute_query}}.real.to_s + "s"

threads = []
puts "Multi-threaded: Testing #{ITERATIONS} iterations"
puts "Multi-threaded: " +  Benchmark.measure { 
   ITERATIONS.times { threads << Thread.new { execute_query } }
   threads.collect{|t| t.join}
}.real.to_s + "s"

===========================================================
$ data_mapper=true ruby mysql_locking_test.rb 
Loading DataMapper
Serial: Testing 4 iterations
  thread: # executing: select sleep(1) from dual
  thread: # executing: select sleep(1) from dual
  thread: # executing: select sleep(1) from dual
  thread: # executing: select sleep(1) from dual
Serial: 4.01330804824829s
Multi-threaded: Testing 4 iterations
  thread: # executing: select sleep(1) from dual
  thread: # executing: select sleep(1) from dual
  thread: # executing: select sleep(1) from dual
  thread: # executing: select sleep(1) from dual
Multi-threaded: 4.01132893562317s


$ ruby mysql_locking_test.rb 
Loading MRI MySQL
Serial: Testing 4 iterations
  thread: # executing: select sleep(1) from dual
  thread: # executing: select sleep(1) from dual
  thread: # executing: select sleep(1) from dual
  thread: # executing: select sleep(1) from dual
Serial: 4.00969815254211s
Multi-threaded: Testing 4 iterations
  thread: # executing: select sleep(1) from dual
  thread: # executing: select sleep(1) from dual
  thread: # executing: select sleep(1) from dual
  thread: # executing: select sleep(1) from dual
Multi-threaded: 4.00785183906555s


$ jruby mysql_locking_test.rb 
Loading JDBC-MySQL
Serial: Testing 4 iterations
  thread: # executing: select sleep(1) from dual
  thread: # executing: select sleep(1) from dual
  thread: # executing: select sleep(1) from dual
  thread: # executing: select sleep(1) from dual
Serial: 4.2802369594573975s
Multi-threaded: Testing 4 iterations
  thread: # executing: select sleep(1) from dual
  thread: # executing: select sleep(1) from dual
  thread: # executing: select sleep(1) from dual
  thread: # executing: select sleep(1) from dual
Multi-threaded: 1.0499329566955566s