Re: Guidance/Help/Book/References?

2012-06-23 Thread Brett Wooldridge
Hi Pavel,

Unfortunately, I'm not writing with any answers.  My company's
software also makes use
of Derby in a high-concurrency setting, and we have encountered
similar issues.  For us,
issues around dead-locks when simply preparing statements has been a
major pain.  We
have indeed had to put in code-level synchronization in various places
to try to deal with
the issues.

Unfortunately, I think you've run into bug 4279...

https://issues.apache.org/jira/browse/DERBY-4279

This deadlock is unique because it can still occur in a properly
designed database.
You are only safe if all of your transactions are very simple and
cannot be interleaved
in a sequence that causes the deadlock, or if your particular statements do not
require a table lock to compile. (For the sake of simplicity, I used
LOCK TABLE in my
example, but any UPDATE statement would fit.)

I had proposed a patch to 4279, but ultimately had to abandon it due
to complex and
non-obvious synchronization issues.  Maybe I'll take another cut at it...

-Brett

On Sat, Jun 23, 2012 at 1:18 AM, Pavel Bortnovskiy
pbortnovs...@jefferies.com wrote:
 Hello, all:



 Derby is used heavily in my project and its tables are frequently accessed
 concurrently by multiple threads. Some threads update one or several tables,
 while other threads perform run select statements against those. I’ve
 written to this group several times whenever errors occurred, but some of
 those message have either been ignored or contained references to fairly
 short explanations on the website. So, the problems continue and it is
 difficult to find the proper solution.



 All problems happen due to the concurrent access to tables. For instance,
 today’s problem had to do with one thread updating one table (the table is
 first truncated and then re-populated to stay in sync with the source of
 data), while the other thread was trying to create a PreparedStatement. So,
 while one thread was truncating a table, another threw this exception
 (probably caused by nested select statements):



 java.sql.SQLException: The conglomerate (1,280) requested does not exist.

     at
 org.apache.derby.impl.jdbc.SQLExceptionFactory40.getSQLException(Unknown
 Source)

     at org.apache.derby.impl.jdbc.Util.generateCsSQLException(Unknown
 Source)

     at
 org.apache.derby.impl.jdbc.TransactionResourceImpl.wrapInSQLException(Unknown
 Source)

     at
 org.apache.derby.impl.jdbc.TransactionResourceImpl.handleException(Unknown
 Source)

     at
 org.apache.derby.impl.jdbc.EmbedConnection.handleException(Unknown Source)

     at
 org.apache.derby.impl.jdbc.ConnectionChild.handleException(Unknown Source)

     at org.apache.derby.impl.jdbc.EmbedPreparedStatement.init(Unknown
 Source)

     at
 org.apache.derby.impl.jdbc.EmbedPreparedStatement20.init(Unknown Source)

     at
 org.apache.derby.impl.jdbc.EmbedPreparedStatement30.init(Unknown Source)

     at
 org.apache.derby.impl.jdbc.EmbedPreparedStatement40.init(Unknown Source)

     at org.apache.derby.jdbc.Driver40.newEmbedPreparedStatement(Unknown
 Source)

     at
 org.apache.derby.impl.jdbc.EmbedConnection.prepareStatement(Unknown Source)

     at
 org.apache.derby.impl.jdbc.EmbedConnection.prepareStatement(Unknown Source)

     at
 com.jefco.fi.commons.database.SqlSyntaxStatement.init(SqlSyntaxStatement.java:76)

     at
 com.jefco.fi.commons.database.SqlSyntaxStatement.init(SqlSyntaxStatement.java:44)

    ...

 Caused by: java.sql.SQLException: The conglomerate (1,280) requested does
 not exist.

     at
 org.apache.derby.impl.jdbc.SQLExceptionFactory.getSQLException(Unknown
 Source)

     at
 org.apache.derby.impl.jdbc.SQLExceptionFactory40.wrapArgsForTransportAcrossDRDA(Unknown
 Source)

     ... 19 more

 Caused by: ERROR XSAI2: The conglomerate (1,280) requested does not exist.

     at
 org.apache.derby.iapi.error.StandardException.newException(Unknown Source)

     at
 org.apache.derby.impl.store.access.heap.HeapConglomerateFactory.readConglomerate(Unknown
 Source)

     at
 org.apache.derby.impl.store.access.RAMAccessManager.conglomCacheFind(Unknown
 Source)

     at
 org.apache.derby.impl.store.access.RAMTransaction.findExistingConglomerate(Unknown
 Source)

     at
 org.apache.derby.impl.store.access.RAMTransaction.getStaticCompiledConglomInfo(Unknown
 Source)

     at
 org.apache.derby.impl.sql.compile.BaseJoinStrategy.fillInScanArgs1(Unknown
 Source)

     at
 org.apache.derby.impl.sql.compile.HashJoinStrategy.getScanArgs(Unknown
 Source)

     at
 org.apache.derby.impl.sql.compile.FromBaseTable.getScanArguments(Unknown
 Source)

     at
 org.apache.derby.impl.sql.compile.FromBaseTable.generateResultSet(Unknown
 Source)

     at org.apache.derby.impl.sql.compile.FromBaseTable.generate(Unknown
 Source)

     at
 org.apache.derby.impl.sql.compile.ProjectRestrictNode.generateMinion(Unknown
 Source)

     at
 

Re: Guidance/Help/Book/References?

2012-06-23 Thread Bryan Pendleton

Derby is used heavily in my project and its tables are frequently accessed 
concurrently by multiple threads. Some threads update
one or several tables, while other threads perform run select statements 
against those. I’ve written to this group several times
whenever errors occurred, but some of those message have either been ignored or 
contained references to fairly short
explanations on the website. So, the problems continue and it is difficult to 
find the proper solution.


...


I must resolve all these errors ASAP and I would like to ask some guidance as 
to how to do it most properly.


Avoiding deadlocks can be very challenging.

I have often found that a very crude mechanism can be used.

In my application, I modified my code to use Derby's LOCK TABLE statement.

For each transaction, I identified which table(s) it was accessing.

At the start of the transaction, my code issued a series of
LOCK TABLE statements:

LOCK TABLE t1 IN EXCLUSIVE MODE;
LOCK TABLE t2 IN EXCLUSIVE MODE;

I did this even for read-only transactions (and used EXCLUSIVE mode
for them, although I certainly could have used SHARE mode).

I thus single-threaded all my Derby accesses, and avoided all deadlocks.

I encapsulated this logic into a common subroutine to avoid
cluttering up the rest of the code; I just have to pass that
subroutine the correct set of tables for this particular
transaction, and the JDBC connection to use.

I ensured that I always locked the tables in the same order (to
avoid deadlocks).

Although this meant that my transaction was somewhat less concurrent
than it might have been:
a) I never had to deal with unexpected deadlocks in the middle of a transaction
b) I found that performance was just fine for my application

If deadlocks are an ongoing persistent problem, you might consider this 
technique.

thanks,

bryan


Re: Guidance/Help/Book/References?

2012-06-23 Thread John English

On 22/06/2012 19:18, Pavel Bortnovskiy wrote:

Hello, all:

Derby is used heavily in my project and its tables are frequently
accessed concurrently by multiple threads. Some threads update one or
several tables, while other threads perform run select statements
against those. I’ve written to this group several times whenever errors
occurred, but some of those message have either been ignored or
contained references to fairly short explanations on the website. So,
the problems continue and it is difficult to find the proper solution.

All problems happen due to the concurrent access to tables. For
instance, today’s problem had to do with one thread updating one table
(the table is first truncated and then re-populated to stay in sync with
the source of data), while the other thread was trying to create a
PreparedStatement. So, while one thread was truncating a table, another
threw this exception (probably caused by nested select statements):


Hi Pavel,
What transaction isolation level are you using for the connections
involved?

--
John English


Guidance/Help/Book/References?

2012-06-22 Thread Pavel Bortnovskiy
Hello, all:

Derby is used heavily in my project and its tables are frequently accessed 
concurrently by multiple threads. Some threads update one or several tables, 
while other threads perform run select statements against those. I've written 
to this group several times whenever errors occurred, but some of those message 
have either been ignored or contained references to fairly short explanations 
on the website. So, the problems continue and it is difficult to find the 
proper solution.

All problems happen due to the concurrent access to tables. For instance, 
today's problem had to do with one thread updating one table (the table is 
first truncated and then re-populated to stay in sync with the source of data), 
while the other thread was trying to create a PreparedStatement. So, while one 
thread was truncating a table, another threw this exception (probably caused by 
nested select statements):

java.sql.SQLException: The conglomerate (1,280) requested does not exist.
at 
org.apache.derby.impl.jdbc.SQLExceptionFactory40.getSQLException(Unknown Source)
at org.apache.derby.impl.jdbc.Util.generateCsSQLException(Unknown 
Source)
at 
org.apache.derby.impl.jdbc.TransactionResourceImpl.wrapInSQLException(Unknown 
Source)
at 
org.apache.derby.impl.jdbc.TransactionResourceImpl.handleException(Unknown 
Source)
at org.apache.derby.impl.jdbc.EmbedConnection.handleException(Unknown 
Source)
at org.apache.derby.impl.jdbc.ConnectionChild.handleException(Unknown 
Source)
at org.apache.derby.impl.jdbc.EmbedPreparedStatement.init(Unknown 
Source)
at org.apache.derby.impl.jdbc.EmbedPreparedStatement20.init(Unknown 
Source)
at org.apache.derby.impl.jdbc.EmbedPreparedStatement30.init(Unknown 
Source)
at org.apache.derby.impl.jdbc.EmbedPreparedStatement40.init(Unknown 
Source)
at org.apache.derby.jdbc.Driver40.newEmbedPreparedStatement(Unknown 
Source)
at org.apache.derby.impl.jdbc.EmbedConnection.prepareStatement(Unknown 
Source)
at org.apache.derby.impl.jdbc.EmbedConnection.prepareStatement(Unknown 
Source)
at 
com.jefco.fi.commons.database.SqlSyntaxStatement.init(SqlSyntaxStatement.java:76)
at 
com.jefco.fi.commons.database.SqlSyntaxStatement.init(SqlSyntaxStatement.java:44)
   ...
Caused by: java.sql.SQLException: The conglomerate (1,280) requested does not 
exist.
at 
org.apache.derby.impl.jdbc.SQLExceptionFactory.getSQLException(Unknown Source)
at 
org.apache.derby.impl.jdbc.SQLExceptionFactory40.wrapArgsForTransportAcrossDRDA(Unknown
 Source)
... 19 more
Caused by: ERROR XSAI2: The conglomerate (1,280) requested does not exist.
at org.apache.derby.iapi.error.StandardException.newException(Unknown 
Source)
at 
org.apache.derby.impl.store.access.heap.HeapConglomerateFactory.readConglomerate(Unknown
 Source)
at 
org.apache.derby.impl.store.access.RAMAccessManager.conglomCacheFind(Unknown 
Source)
at 
org.apache.derby.impl.store.access.RAMTransaction.findExistingConglomerate(Unknown
 Source)
at 
org.apache.derby.impl.store.access.RAMTransaction.getStaticCompiledConglomInfo(Unknown
 Source)
at 
org.apache.derby.impl.sql.compile.BaseJoinStrategy.fillInScanArgs1(Unknown 
Source)
at 
org.apache.derby.impl.sql.compile.HashJoinStrategy.getScanArgs(Unknown Source)
at 
org.apache.derby.impl.sql.compile.FromBaseTable.getScanArguments(Unknown Source)
at 
org.apache.derby.impl.sql.compile.FromBaseTable.generateResultSet(Unknown 
Source)
at org.apache.derby.impl.sql.compile.FromBaseTable.generate(Unknown 
Source)
at 
org.apache.derby.impl.sql.compile.ProjectRestrictNode.generateMinion(Unknown 
Source)
at 
org.apache.derby.impl.sql.compile.ProjectRestrictNode.generate(Unknown Source)
at 
org.apache.derby.impl.sql.compile.ProjectRestrictNode.generateMinion(Unknown 
Source)
at 
org.apache.derby.impl.sql.compile.ProjectRestrictNode.generate(Unknown Source)
at org.apache.derby.impl.sql.compile.GroupByNode.generate(Unknown 
Source)
at 
org.apache.derby.impl.sql.compile.ProjectRestrictNode.generateMinion(Unknown 
Source)
at 
org.apache.derby.impl.sql.compile.ProjectRestrictNode.generate(Unknown Source)
at 
org.apache.derby.impl.sql.compile.SubqueryNode.generateExpression(Unknown 
Source)
at 
org.apache.derby.impl.sql.compile.BinaryOperatorNode.generateExpression(Unknown 
Source)
at 
org.apache.derby.impl.sql.compile.ProjectRestrictNode.generateMinion(Unknown 
Source)
at 
org.apache.derby.impl.sql.compile.ProjectRestrictNode.generate(Unknown Source)
at org.apache.derby.impl.sql.compile.UnionNode.generate(Unknown Source)
at 
org.apache.derby.impl.sql.compile.NormalizeResultSetNode.generate(Unknown 
Source)
at 
org.apache.derby.impl.sql.compile.ProjectRestrictNode.generateMinion(Unknown 
Source)