org.apache.jena.graph.compose.MultiUnion does not somehow automatically handle 
transactions.

If you read from a Multiunion, you need to manage transaction boundaries around 
that read, in that thread. If you don't, you will be working 
non-transactionally against the dataset. That is never a good idea and for 
TDB1, you _cannot_ work transactionally and non-transactionally against the 
dataset at the same time.

Adam Soroka

> On Dec 28, 2017, at 8:17 AM, George News <[email protected]> wrote:
> 
> 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
>>>>>>>> 
>>>>>>> 
>>>>>>> 
>>>>>>> 
>>>>> 
>>>>> 
>>>> 
>> 

Reply via email to