BaseXdb / basex

BaseX Main Repository.
http://basex.org
BSD 3-Clause "New" or "Revised" License
661 stars 268 forks source link

Server: Overlapping file locks during highly-concurrent querying #574

Closed LukasK closed 11 years ago

LukasK commented 11 years ago

[basex-talk] BUG# Multiple Thread try to execute some Query

import java.io.IOException;
import java.util.ArrayList;

import org.basex.server.ClientSession;

public class Example
{
  // create the database "factbook" from factbook.xml (see demo of basex page)
  public static void main(String[] args) throws IOException, InterruptedException
  {
    ArrayList<TestThread> threads = new ArrayList<>();
    for (int i = 0; i < 100; i++)
    {
      TestThread t = new TestThread();
      threads.add(t);
    }
    // start all threads
    for (TestThread t : threads)
    {
      t.start();
    }
    // wait all threads
    for (TestThread t : threads)
    {
      t.join();
    }
    System.out.println("DONE");
  }
}

class TestThread extends Thread
{
  ClientSession session;
  int error;

  //countries
  String[] countries = { "Albania", "Andorra", "Austria", "Belarus", "Belgium", "Bosnia", "and", "Herzegovina",
  "Bulgaria", "Croatia", "Czech", "Rep. Czech", "Republic", "Denmark", "Estonia", "Faroe", "Islands", "Finland",
  "France", "Germany", "Gibraltar", "Greece", "Guernsey", "Vatican", "City", "Holy", "See", "Hungary", "Iceland" };

  @Override
  public void run()
  {
    try
    {
      session = new ClientSession("localhost", 1984, "admin", "admin");
      // execute the query 100 times
      for (int i = 0; i < 100; i++)
      {
        doSomething();
      }
    }
    catch (IOException e)
    {
      // Stop if the Error occur (to see the error message)
      e.printStackTrace();
      System.exit(0);
    }
    finally
    {
      try
      {
        session.close();
      }
      catch (IOException e)
      {
        // TODO Auto-generated catch block
        e.printStackTrace();
      }
    }
  }

  private void doSomething() throws IOException
  {
    int index = (int) (Math.random() * countries.length);
    String command = "xquery for $e in collection('factbook')/mondial/country[name=\"" + countries[index]
    + "\"] return $e";
    String output = session.execute(command);
    System.out.println(this.getName() + ": Query\n" + output);
  }
}
ChristianGruen commented 11 years ago

Short-term solution: setting option PARALLEL to 1.

srinivasanrm commented 11 years ago

Hi Christian, I tried a similar test java app with multiple threads running a simple read query and confirmed that I don't see OverlappingFileLockException anymore. Thanks for the fix.

ChristianGruen commented 11 years ago

Great! Thanks for the quick feedback.