Jody,

I've created a simple test case, which reproduce the problem even without
multithreads scenario.

So just copy and add this test method in *JDBCFeatureLockingTest.java* in
gt-jdbc module and then run JUnit test *PostgisFeatureLocking.java*

Let me know if you can see the same problem that I saw.

Thanks,
Yingqi

    public void testLockFeaturesWithFilterWithTransactionLock() throws
Exception {
        // create a DefaultTransaction
        Transaction tx = new DefaultTransaction();
        // use TransactionLock
        FeatureLock lock = FeatureLock.TRANSACTION;
        // switch to use MemoryLock, everything is fine
        //FeatureLock lock = FeatureLockFactory.generate(tname("ft1"), 60 *
60 * 1000);
        store.setTransaction(tx);
        store.setFeatureLock(lock);
        // authorize the transaction to modify features
        tx.addAuthorization(lock.getAuthorization());

        // create filters
        FilterFactory ff = dataStore.getFilterFactory();
        PropertyIsEqualTo f = ff.equals(ff.property(aname("intProperty")),
ff.literal(1));
        // get feature writer
        FeatureWriter<SimpleFeatureType, SimpleFeature> writer =
dataStore.getFeatureWriter(tname("ft1"), f, tx);
        try {
            //lock features
            int locked = store.lockFeatures(f);
            // only one should be locked
            assertEquals(1, locked);
            while(writer.hasNext()) {
                SimpleFeature feature = (SimpleFeature) writer.next();

                // modify feature attribute
                feature.setAttribute(aname("intProperty"), new
Integer(100));
                //tx.addAuthorization(lock.getAuthorization());    // not
necessary
                writer.write();
            }
            //tx.addAuthorization(lock.getAuthorization());
            // commit changes back to database, and the changes actually is
committed
            tx.commit();
        } catch(FeatureLockException fle) {
            fle.printStackTrace();
        } catch(IOException ioe) {
            ioe.printStackTrace();
        } catch(java.lang.IllegalMonitorStateException lmse) {
            // this is the exception I'm talking about
            // it happens when the TransactionLock is trying to release
itself after commit()
            lmse.printStackTrace();
            assertTrue(false);
        } catch(Exception e) {
            e.printStackTrace();
        } finally {
            //tx.addAuthorization(lock.getAuthorization());
            try {
                writer.close();
                tx.close();
            } catch(IOException ioe) {
                ioe.printStackTrace();
            }
        }
    }

On Thu, Sep 9, 2010 at 11:05 PM, Jody Garnett <[email protected]>wrote:

> So we may of found a problem?
>
> Could you construct a test case I can run; I am having a hard time remember
> the difference between memory lock and transaction lock and could use a
> refresher :-)
>
> Jody
>
> On 08/09/2010, at 5:23 PM, Yingqi Tang wrote:
>
> Jody,
>
> Thanks for pointing out the samples in "main" module. I actually went
> through those JUnit tests but they are all either using AUTO_COMMIT
> transaction or the MemoryLock (the one generated by calling
> FeatureLockFactory.generate()), and there are actually some similar ones in
> JDBC module tests. But none of those uses the TransactionLock, which is the
> one that causes problem. I actually did an experiment by commenting out a
> chunk of code in InProcessLockingManager class that only relates to
> TransactionLock (the code will only be executed when FeatureLock.TRANSACTION
> is used), and all the JUnit tests still passed without problem.
>
> The code I was looking at is in InProcessLockingManager line 89 - 111
>
>             if (lock instanceof TransactionLock) {
>                 TransactionLock tlock = (TransactionLock) lock;
>
>                 if (transaction == tlock.transaction) {
>                     // lock already held by this transacstion
>                     // we could just consider returning here
>                     //
>                     throw new FeatureLockException("Transaction Lock is
> already held by this Transaction",
>                         featureID);
>                 } else {
>                     // we should wait till it is available and then grab
>                     // the lock
>                     try {
>                         synchronized (tlock) {
>                             tlock.wait();
>                         }
>
>                         lock = getLock(typeName, featureID);
>                     } catch (InterruptedException interupted) {
>                         throw new FeatureLockException("Interupted while
> waiting for Transaction Lock",
>                             featureID, interupted);
>                     }
>                 }
>
>
>
> On Wed, Sep 8, 2010 at 4:06 AM, Jody Garnett <[email protected]>wrote:
>
>> - 
>> FeatureLockTest.java<http://svn.osgeo.org/geotools/trunk/modules/library/main/src/test/java/org/geotools/data/FeatureLockTest.java>
>> <http://svn.osgeo.org/geotools/trunk/modules/library/main/src/test/java/org/geotools/data/FeatureLockTest.java>
>> -
>>
>>
>> http://svn.osgeo.org/geotools/trunk/modules/library/main/src/test/java/org/geotools/data/memory/MemoryDataStoreTest.java
>>
>>
>> Examples
>>
>>     public void testLockFeatures() throws IOException {
>>         FeatureLock lock = FeatureLockFactory.generate("test", 3600);
>>         FeatureLocking<SimpleFeatureType, SimpleFeature> road = 
>> (FeatureLocking<SimpleFeatureType, SimpleFeature>) 
>> data.getFeatureSource("road");
>>         road.setFeatureLock(lock);
>>
>>         assertFalse(isLocked("road", "road.rd1"));
>>         road.lockFeatures();
>>         assertTrue(isLocked("road", "road.rd1"));
>>     }
>>
>>
>> public void testUnLockFeatures() throws IOException {
>>         FeatureLock lock = FeatureLockFactory.generate("test", 3600);
>>         FeatureLocking<SimpleFeatureType, SimpleFeature> road = 
>> (FeatureLocking<SimpleFeatureType, SimpleFeature>) 
>> data.getFeatureSource("road");
>>         road.setFeatureLock(lock);
>>         road.lockFeatures();
>>
>>         try {
>>             road.unLockFeatures();
>>             fail("unlock should fail due on AUTO_COMMIT");
>>         } catch (IOException expected) {
>>         }
>>         Transaction t = new DefaultTransaction();
>>         road.setTransaction(t);
>>         try {
>>             road.unLockFeatures();
>>             fail("unlock should fail due lack of authorization");
>>         } catch (IOException expected) {
>>         }
>>         t.addAuthorization(lock.getAuthorization());
>>         road.unLockFeatures();
>>     }
>>
>>
>> public void testLockFeatureInteraction() throws IOException {
>>         FeatureLock lockA = FeatureLockFactory.generate("LockA", 3600);
>>         FeatureLock lockB = FeatureLockFactory.generate("LockB", 3600);
>>         Transaction t1 = new DefaultTransaction();
>>         Transaction t2 = new DefaultTransaction();
>>         FeatureLocking<SimpleFeatureType, SimpleFeature> road1 = 
>> (FeatureLocking<SimpleFeatureType, SimpleFeature>) 
>> data.getFeatureSource("road");
>>         FeatureLocking<SimpleFeatureType, SimpleFeature> road2 = 
>> (FeatureLocking<SimpleFeatureType, SimpleFeature>) 
>> data.getFeatureSource("road");
>>         road1.setTransaction(t1);
>>         road2.setTransaction(t2);
>>         road1.setFeatureLock(lockA);
>>         road2.setFeatureLock(lockB);
>>
>>         assertFalse(isLocked("road", "road.rd1"));
>>         assertFalse(isLocked("road", "road.rd2"));
>>         assertFalse(isLocked("road", "road.rd3"));
>>
>>         road1.lockFeatures(rd1Filter);
>>         assertTrue(isLocked("road", "road.rd1"));
>>         assertFalse(isLocked("road", "road.rd2"));
>>         assertFalse(isLocked("road", "road.rd3"));
>>
>>         road2.lockFeatures(rd2Filter);
>>         assertTrue(isLocked("road", "road.rd1"));
>>         assertTrue(isLocked("road", "road.rd2"));
>>         assertFalse(isLocked("road", "road.rd3"));
>>
>>         try {
>>             road1.unLockFeatures(rd1Filter);
>>             fail("need authorization");
>>         } catch (IOException expected) {
>>         }
>>         t1.addAuthorization(lockA.getAuthorization());
>>         try {
>>             road1.unLockFeatures(rd2Filter);
>>             fail("need correct authorization");
>>         } catch (IOException expected) {
>>         }
>>         road1.unLockFeatures(rd1Filter);
>>         assertFalse(isLocked("road", "road.rd1"));
>>         assertTrue(isLocked("road", "road.rd2"));
>>         assertFalse(isLocked("road", "road.rd3"));
>>
>>         t2.addAuthorization(lockB.getAuthorization());
>>         road2.unLockFeatures(rd2Filter);
>>         assertFalse(isLocked("road", "road.rd1"));
>>         assertFalse(isLocked("road", "road.rd2"));
>>         assertFalse(isLocked("road", "road.rd3"));
>>     }
>>
>>  public void testGetFeatureLockingExpire() throws Exception {
>>         FeatureLock lock = FeatureLockFactory.generate("Timed", 500);
>>         FeatureLocking<SimpleFeatureType, SimpleFeature> road = 
>> (FeatureLocking<SimpleFeatureType, SimpleFeature>) 
>> data.getFeatureSource("road");
>>         road.setFeatureLock(lock);
>>         assertFalse(isLocked("road", "road.rd1"));
>>         road.lockFeatures(rd1Filter);
>>         assertTrue(isLocked("road", "road.rd1"));
>>         long then = System.currentTimeMillis();
>>         do {
>>             Thread.sleep( 15 );
>>         } while ( then > System.currentTimeMillis() - 515 );
>>         assertFalse(isLocked("road", "road.rd1"));
>>     }
>>
>>
>> On 08/09/2010, at 12:19 AM, Augusttown wrote:
>>
>>
>> Jody,
>>
>> Is there a JUnit test or example written for testing
>> FeatureLock.TRANSACTION? There seems to be a problem when using
>> FeatureLock.TRANSACTION to lock and modify features. There is always a
>> java.lang.IllegalMonitorStateException exception being thrown out when the
>> release() is called on instance of TransactionLock. The change has
>> actually
>> been committed to the database already before the exception.
>>
>> I'm kind of stuck here, and I don't think there is any JUnit tests or
>> sample
>> written using FeatureLock.TRANSACTION. Will source code of GeoServer shed
>> any light on this?
>>
>> The code below will reproduce the issue:
>>
>> for(int i=0; i<4; i++) {
>>            // spread a new thread
>>            final String id = String.valueOf(i);
>>            threadPool.execute(
>>                new Runnable() {
>>                    public void run() {
>>                        try {
>>                            String targetFeatureTypeName =
>> "sf_pizzastores_wgs84";
>>                            JDBCFeatureStore jdbcFeatureStore =
>> (JDBCFeatureStore)jdbcDataStore.getFeatureSource(targetFeatureTypeName);
>>
>>                            Transaction transaction = new
>> DefaultTransaction();
>>
>>                            FeatureLock featureLock =
>> FeatureLock.TRANSACTION;
>>
>>                            String lockId = featureLock.getAuthorization();
>>                            jdbcFeatureStore.setTransaction(transaction);
>>
>>                            jdbcFeatureStore.setFeatureLock(featureLock);
>>
>>                            transaction.addAuthorization(lockId);
>>
>>                            FeatureWriter<SimpleFeatureType, SimpleFeature>
>> featureWriter = jdbcDataStore.getFeatureWriter(targetFeatureTypeName,
>> transaction);
>>
>>                            jdbcFeatureStore.lockFeatures();
>>
>>                            while(featureWriter.hasNext()) {
>>                                SimpleFeature simpleFeature =
>> featureWriter.next();
>>                                String store_id =
>> (String)simpleFeature.getAttribute("store_id");
>>                                simpleFeature.setAttribute("name", "ps"+ id
>> + "." + store_id);
>>
>>                                transaction.addAuthorization(lockId);
>>
>>                                featureWriter.write();
>>
>>                            }
>>                            try {
>>
>>                                transaction.addAuthorization(lockId);
>>
>>                                transaction.commit();
>>
>>                            } catch(Exception e) {
>>
>>                                 transaction.rollback();
>>                                 e.printStackTrace();
>>                            } finally {
>>                                transaction.addAuthorization(lockId);
>>
>>                                jdbcFeatureStore.unLockFeatures();
>>
>>                                featureWriter.close();
>>                                transaction.close();
>>                            }
>>                        } catch(Exception e) {
>>
>>                            e.printStackTrace();
>>                        } finally {
>>                        }
>>                    }
>>                }
>>            );
>>        }
>>        threadPool.shutdown();
>> --
>> View this message in context:
>> http://osgeo-org.1803224.n2.nabble.com/How-to-use-FeatureLock-TRANSACTION-when-modifying-features-and-committing-changes-tp5491953p5508478.html
>> Sent from the geotools-gt2-users mailing list archive at Nabble.com.
>>
>>
>> ------------------------------------------------------------------------------
>> This SF.net Dev2Dev email is sponsored by:
>>
>> Show off your parallel programming skills.
>> Enter the Intel(R) Threading Challenge 2010.
>> http://p.sf.net/sfu/intel-thread-sfd
>> _______________________________________________
>> Geotools-gt2-users mailing list
>> [email protected]
>> https://lists.sourceforge.net/lists/listinfo/geotools-gt2-users
>>
>>
>>
>
>
------------------------------------------------------------------------------
Start uncovering the many advantages of virtual appliances
and start using them to simplify application deployment and
accelerate your shift to cloud computing
http://p.sf.net/sfu/novell-sfdev2dev
_______________________________________________
Geotools-gt2-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/geotools-gt2-users

Reply via email to