Giter VIP home page Giter VIP logo

jacis's Introduction

CI Java 8 CodeQL

jacis

Java ACI Store - Transient and transactional store for Java objects.

The name of the store is derived from the acronym ACID (Atomicity, Consistency, Isolation, Durability) describing the properties of transactions. The store is designed to fulfill the first three of these properties but not the Durability.

The JACIS project follows the semantic versioning policy (see https://semver.org/, API indicated by JacisApi Annotation).

For more information see https://github.com/JanWiemer/jacis/wiki

jacis's People

Contributors

fullben avatar janwiemer avatar ssimarkus avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

jacis's Issues

Tracking modifications in tracked views has to be exception safe

Calling the onModification of a tracked view should be wrapped with a try-catch. An exception should not prevent cleanup of the transaction (otherwise objects may remain locked for this transaction).

see method: org.jacis.store.StoreTxDemarcationExecutor.trackModification(JacisStoreImpl<K, TV, CV>, K, TV, TV, JacisTransactionHandle)

Remove logging configuration from repository

The release version I tested (2.0.6) contains a logging configuration which causes the framework to write a log to file at runtime. Shouldn't it be the responsibility of the users of the framework to provide a logging config/decide on what they want to be logged?

Originally posted by @fullben in #18

  • Remove lockback.xml
  • Add template lockback.xml as suggestion to start

Add withLocalTx getting a supplyer task and returning the result

As far as I understand it, there are two general ways for running transactions:

// Option 1
...
JacisLocalTransaction tx = container.beginLocalTransaction();
// Do work
tx.commit();

...

// Option 2
container.withLocalTx(() -> {...});

If I'm not mistaken, using option 1 would not result in a rollback being executed if an exception occurs in my block of work, while a rollback would be attempted when using option 2 and exception occurs.
Assuming this is the case, wouldn't it make sense to offer something like public <T> T withLocalTx(Supplier<T> task) alongside the existing public void withLocalTx(Runnable task)? I often find myself in lengthy transactions that in the end produce some value which I want to return.
Not sure if the above is a feature request or if I'm just missing something...

Originally posted by @fullben in #19

Make nullsafe: TrackedViewRegistry.getSubView

Avoid NPEs like:

java.lang.NullPointerException
	at org.jacis.store.TrackedViewRegistry.lambda$getSubView$3(TrackedViewRegistry.java:125)
	at org.jacis.store.JacisStoreImpl.withReadLock(JacisStoreImpl.java:442)
	at org.jacis.store.JacisStoreImpl.computeAtomic(JacisStoreImpl.java:305)
	at org.jacis.store.TrackedViewRegistry.getSubView(TrackedViewRegistry.java:114)

Solution idea:

Require the clustered view to return a (not null) value and document this in JavaDoc. If null is returned throw a NPE with an appropriate comment

Dirty Check not working

Dirty Check is currently not working as expected.
Dirty objects are not recognized as updated

Memory Leak caused by ThreadLocal JacisContainer.lastFinishedTransactionInfo

If many different threads start transactions with a JACIS container and afterwards the container is no longer used (sometimes a usecase specially in unit test suites) those thread locals are never cleaned up.

Improvement would be to provide a destroy method to clean-up those resources (would require to store the information in a map instead a thread local...).

Support executing trackModifications in the order of the update statements

The desire is to preserve to order of the updates (for different store entries) when calling the trackModification() methods of tracked views or modification listeners. This can be achieved wit some restrictions and some performance costs:

  • The order of trackModification() calls should be be defined on the time the update() method is called for the object (the store can not know the the time of the modifications itself);
  • Only the complete modification on an object during the whole transaction are tracked. During the transaction there may be more than one update() calls for a single object. Therefore we define that the last update call defines the order of trackModification() calls.
  • We have to store a timestamp or a sequence number for the update of each modified entry.
  • During the preparing phase of the transaction the modified entries have to be sorted according to this timestamp / sequence number. This may have performance impacts, therefore it should be possible to disable ordering of the trackModification() calls by a flag in the store meta data (object type spec)).

NoSuchElementException in checkRemoveCommittedEntry when copying values of TX view map

Version: 2.0.1:

Under heavy load the following exception occured:

Caused by: java.util.NoSuchElementException
    at org.jacis.util.ConcurrentWeakHashMap$HashIterator.nextEntry(ConcurrentWeakHashMap.java:1231)
    at org.jacis.util.ConcurrentWeakHashMap$ValueIterator.next(ConcurrentWeakHashMap.java:1266)
    at java.base/java.util.AbstractCollection.toArray(AbstractCollection.java:144)
    at java.base/java.util.ArrayList.<init>(ArrayList.java:179)
    at org.jacis.store.JacisStoreImpl.checkRemoveCommittedEntry(JacisStoreImpl.java:557)
    at org.jacis.store.StoreTxDemarcationExecutor.executeCommit(StoreTxDemarcationExecutor.java:115)
    at org.jacis.store.JacisStoreImpl.lambda$internalCommit$20(JacisStoreImpl.java:485)
    at org.jacis.store.JacisStoreImpl.lambda$runnableWrapper$24(JacisStoreImpl.java:596)
    at org.jacis.store.JacisStoreImpl.withWriteLock(JacisStoreImpl.java:579)
    at org.jacis.store.JacisStoreImpl.internalCommit(JacisStoreImpl.java:485)
    at org.jacis.container.JacisContainer.internalCommit(JacisContainer.java:522)
    at org.jacis.plugin.txadapter.jta.AbstractJacisTransactionAdapterJTA$JacisSync.afterCompletion(AbstractJacisTransactionAdapterJTA.java:199)

Add helper executing a task within a (local) JACIS transaction with retry mechanism

Generally retrying the whole transaction is the solution for stale object exceptions when using optimistic locking (similar e.g. in hibernate...). I also always use a helper class starting the transaction, executing a task and finally committing the transaction. This helper class also cares about the retry. The helper class looks similar to your suggestion (I usually add an increasing delay between the retries). I implemented the helper class outside the store since I usually use it with global JTA transactions and the helper class is more general.

Anyway I will think about adding a helper class (or method) doing the same for local transactions...

Originally posted by @JanWiemer in #26 (comment)

Parallel streaming with JacisStores

While calling parallel() on the read-only streaming methods of a store seems to have no negative side effects, I have encountered an issue when calling parallel() on the regular streaming methods (stream(), stream(Predicate<T> p)...):

This sometimes ends up in ReadOnlyExceptions. My guess is that this is due to the parallelism. I would assume that the threadWithWriteAccess field of the AbstractReadOnlyModeSupportingObject is set to one of the threads executing the stream task, which sometimes might not be the thread which is tasked with further processing the stream result. When this thread then attempts to resume its work, it causes an exception, as it is not the thread which initially processed the object.

If my assessment is correct, this is probably not fixable and will remain a framework limitation.

Add bulk insert operation with key-extractor method

Currently, new values can only be added to stores by calling the update(K key, TV value) method.

Would it be possible to implement a method along the signature of void update(Function<TV, K> keyFunction, Collection<TV> value) for batch inserts?

Originally posted by @fullben in #22

ConcurrentModificationException in JacisIndexRegistry.getFromNonUniqueIndexReadOnly

Following exception occured:

Caused by: java.util.ConcurrentModificationException
at java.base/java.util.HashMap$HashIterator.nextNode(HashMap.java:1605)
at java.base/java.util.HashMap$KeyIterator.next(HashMap.java:1628)
at org.jacis.index.JacisIndexRegistry.getFromNonUniqueIndexReadOnly(JacisIndexRegistry.java:334)
at org.jacis.index.JacisNonUniqueIndex.getReadOnly(JacisNonUniqueIndex.java:59)

It seems that the nonUniqueIndexDataMap is initilized with a simple HashSet instead of a ConcurrentHashSet in method org.jacis.index.JacisIndexRegistry#trackModificationAtNonUniqueIndex. Changing this to ConcurrentHashSet should fix the issue.

Syncronize Access on org.jacis.store.StoreEntry

Otherwise e.g. NPE like the following could happen:

java.lang.NullPointerException
   at org.jacis.store.StoreEntry.isLockedForOtherThan(StoreEntry.java:56)
   at org.jacis.store.StoreEntryTxView.assertNotStale(StoreEntryTxView.java:88)
   at org.jacis.store.JacisStoreImpl.checkStale(JacisStoreImpl.java:164)

Exception in tracked view may cause lock for prepared transactions not to be cleaned up appropriately

Exception during modification of a tracked view or another modification listener currently immediately returns from the commit and no cleanup is done. Instead we have to clean up the lock markers the prepared transaction has on the modified objects. Otherwise later another TX would get a stale object exception because of the current TX even if it is finished a long time ago. Additionally even if one modification causes an exception we should at least try to do the other modifications. If multiple exceptions occur we should collect them as suppressed exceptions.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.