Can you give a complete example? How are you calling MultiUnion? Are you calling txn read on the dataset then building the union, then calling txn write to update the graph?
Dick -------- Original message --------From: George News <[email protected]> Date: 28/12/2017 13:17 (GMT+00:00) To: [email protected] Subject: Re: Txn code not handling type of transaction On 2017-12-27 19:32, Andy Seaborne wrote: > > > On 27/12/17 18:19, George News wrote: >> One think I have forgotten to mention is that I'm using a static >> variable to store the dataset reference. Is this important? > > No. > > The top layer of transaction code uses ThreadLocal variables. > > Internally, there are Transaction objects. > > Andy Another doubt on the issue with transactions. I'm generating Multiunions from the same dataset graphs. While in one thread I'm reading from a multiunion, on another thread I'm writing to one of the graphs included in the multiunion (standalone graph, not multiunion). I have modified my code to use Txn everywhere and still having issues. This is why I'm asking about how multiunions are handle concerning transactions. >> >> >> On 2017-12-27 19:13, George News wrote: >>> Just out of curiosity, just in case the problem is that everything is >>> done in the same thread. Do you know if Wildfly is handling every >>> request under the same thread? I guess not, it will be really strange. > >>> >>> The point is that I have one REST endpoint for writing and another for >>> reading. Writing is done almost per 1 to 10 seconds. If I execute a >>> reading that takes longer than that, I get the exception on alloc-write. >>> >>> Thanks a lot. I just don't know why it is happening. Now I think the >>> code is using Txn (I have one point where I copied the Txn.java >>> behaviour) and still got the error. >>> >>> On 2017-12-27 17:18, ajs6f wrote: >>>>> Then nesting is not safe as you might have open initially a read >>>>> transaction and then include a write. If the parent one is a write >>>>> there >>>>> shouldn't be such an issue (I guess). >>>> >>>> Actual nesting is not supported right now, period. Transactions in >>>> Jena are currently thread-local, so what you describe above I would >>>> see as a mistaken use of the API. If a client needs to move from a >>>> READ to a WRITE transaction, it's usually appropriate to close the >>>> transaction and open a new one (transactions in TIM, for instance, >>>> are snapshot isolated, and I believe the same is true of TDB2). >>>> Transactional objects _should not_ be passed from thread to thread >>>> with open transactions, unless additional client machinery is in >>>> place to manage those transactions, such as Dick has described in >>>> another thread (using thread proxies). >>>> >>>> Promotion machinery does exist in Jena but I am not aware that any >>>> of the dataset implementations actually support it right now. I >>>> could be wrong about that, since I didn't write the promotion code. >>>> Jena isn't a SQL database and doesn't offer the same kinds of >>>> guarantees or tradeoffs. Correctly promoting transactions in the >>>> absence of information about data dependencies is non-trivial. >>>> >>>> That having been said, it should be possible to add a "transaction >>>> type" method to transactional objects, within the "thread-local" >>>> design. Some dataset implementations already have one, e.g. >>>> DatasetGraphInMemory::transactionType. You might want to start by >>>> adding it to the o.a.j.sparql.core.Transactional interface and then >>>> "catching up" the implementation code to build up a PR. >>>> >>>> Adam Soroka >>>> >>>>> On Dec 27, 2017, at 6:53 AM, George News <[email protected]> wrote: >>>>> >>>>> On 2017-12-27 12:29, Claude Warren wrote: >>>>>> I recently wrote some code to try to handle a similar situation. >>>>>> In my >>>>>> case I knew I needed a transaction to be active at various points >>>>>> so I >>>>>> created a TransactionHolder. I create the holder and passing the >>>>>> object >>>>>> that has implements Transactional as well as the type of ReadWrite >>>>>> I want. >>>>>> >>>>>> If the transaction is active it does nothing (and I hope the proper >>>>>> transaction has been started) otherwise It starts the transaction. >>>>>> Ad the end I call commit or abort as appropriate. If I did not >>>>>> start the >>>>>> transaction the commit, abort or end is ignored. >>>>> >>>>> I see the same problem in your code as I pointed out before. A >>>>> transaction behaves differently if it is READ or WRITE and in your >>>>> code >>>>> there is not such a thing. Actually the isInTransaction() doesn't give >>>>> you this information. >>>>> >>>>> Then nesting is not safe as you might have open initially a read >>>>> transaction and then include a write. If the parent one is a write >>>>> there >>>>> shouldn't be such an issue (I guess). >>>>> >>>>> Just for you to know, your code is more or less integrated in [1], so >>>>> you can "update" your code. >>>>> >>>>> [1]: jena/jena-arq/src/main/java/org/apache/jena/system/Txn.java >>>>> >>>>> >>>>>> I think there may be an issue with abort in that it should >>>>>> probablyset up >>>>>> end() to throw an exception when I have not created the >>>>>> transaction so >>>>>> that the outer transaction will fail. >>>>>> >>>>>> import org.apache.jena.query.ReadWrite; >>>>>> import org.apache.jena.sparql.core.Transactional; >>>>>> >>>>>> public class TransactionHolder { >>>>>> private final Transactional txn; >>>>>> private final boolean started; >>>>>> private final ReadWrite rw; >>>>>> >>>>>> public TransactionHolder( Transactional txn, ReadWrite rw ) >>>>>> { >>>>>> this.txn = txn; >>>>>> this.rw = rw; >>>>>> started = ! txn.isInTransaction(); >>>>>> if (started) >>>>>> { >>>>>> txn.begin( rw ); >>>>>> } >>>>>> } >>>>>> >>>>>> public boolean ownsTranaction() { >>>>>> return started; >>>>>> } >>>>>> >>>>>> public void commit() { >>>>>> if (started) { >>>>>> txn.commit(); >>>>>> } >>>>>> } >>>>>> >>>>>> public void abort() { >>>>>> if (started) >>>>>> { >>>>>> txn.abort(); >>>>>> } >>>>>> } >>>>>> >>>>>> public void end() { >>>>>> if (started) { >>>>>> txn.end(); >>>>>> } >>>>>> } >>>>>> >>>>>> } >>>>>> >>>>>> >>>>>> On Wed, Dec 27, 2017 at 11:03 AM, dandh988 <[email protected]> >>>>>> wrote: >>>>>> >>>>>>> You cannot nest transactions nor can you promote a read to a write. >>>>>>> You need to rewrite your code or use txn which correctly checks if a >>>>>>> transaction is available and if not will begin the correct one, >>>>>>> either READ >>>>>>> or WRITE. >>>>>>> >>>>>>> >>>>>>> Dick >>>>>>> -------- Original message --------From: George News >>>>>>> <[email protected]> >>>>>>> Date: 27/12/2017 10:27 (GMT+00:00) To: Jena User Mailing List < >>>>>>> [email protected]> Subject: Txn code not handling type of >>>>>>> transaction >>>>>>> Hi, >>>>>>> >>>>>>> As you know from other threads I'm having some issues with >>>>>>> transactions. >>>>>>> Your suggestion is to use Txn instead of begin/end. Just for >>>>>>> curiosity I >>>>>>> have checked the Txn code at [1] and it seems that inside you use >>>>>>> begin/end. >>>>>>> >>>>>>> However I have a doubt concerning how you handle the begin/end >>>>>>> for READ >>>>>>> and WRITE. It seems that you open a transaction based on >>>>>>> txn.isInTransaction(), but how do you know if it is a READ or WRITE? >>>>>>> >>>>>>> If you create something like: >>>>>>> >>>>>>> Txn.executeRead(dataset, { >>>>>>> Txn.executeWrite(dataset, { >>>>>>> // Whatever >>>>>>> } >>>>>>> } >>>>>>> } >>>>>>> >>>>>>> the txn.begin(ReadWrite.WRITE) is not called and therefore it >>>>>>> might be >>>>>>> leading to unexepected behaviours for the txn.commit(). >>>>>>> >>>>>>> could you give some hints on how this is handle internally? >>>>>>> Before fully >>>>>>> modify the code I have, it might be easier to replicate the txn >>>>>>> behaviour ;) but I would like to know the above (if possible). >>>>>>> >>>>>>> As always, thanks in advanced >>>>>>> Jorge >>>>>>> >>>>>>> [1]: jena/jena-arq/src/main/java/org/apache/jena/system/Txn.java >>>>>>> >>>>>> >>>>>> >>>>>> >>>> >>>> >>> >
