> 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