Jody,
Just wonder if you had chance to try this test case to see if the issue I
encountered is a real issue or user error?
Thanks
On Fri, Sep 10, 2010 at 11:56 AM, Yingqi Tang <[email protected]> wrote:
> 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