On 2017-12-13 00:11, Andy Seaborne wrote:
> On 12/12/17 23:04, George News wrote:
>> On 2017-12-12 23:58, Andy Seaborne wrote:
>>>
>>>
>>> On 12/12/17 22:54, George News wrote:
>>>>>> I'm planning on changing the class/methods call hierarchy in order to
>>>>>> use transactions only on the upper levels, so this way I will be only
>>>>>> opening one transaction and handle everything within it. The
>>>>>> problem is
>>>>>> that this is a major change, and will remove the autonomy from each
>>>>>> class, but if this is the price to make the code stable I will
>>>>>> have to
>>>>>> do so.
>>>>> Txn and explicit control will bite you.
>>>> Then from your comment above, and this one (which I hope code doesn't
>>>> bite ;)) I will be changing the code to remove references to begin/end
>>>> and try to use Txn as much as possible.
>>>>
>>>> However, I cannot do for every part of the code, as the ResultSet is
>>>> handle in different functions (one begin() transaction, another
>>>> presents/adapts results and end transaction()). The main problem is
>>>> that
>>>> this transaction is the outer one.
>>>
>>> try(QueryExecution qExec = ...) {
>>>     ResultSet rs = ResultSetFactory.copyResults(qExec.exexSelect());
>>>     return rs;
>>> }
>>>
>>> Once copied, the result set is not dependent dataset and so not
>>> dependent on the transaction.
>>
>> I know that, but some of the resultsets are 10Mb-50Mb or more in size,
>> and I don't know what is the impact in performance in case many request
>> arrives at the system.
>>
>> Currently I'm directly streaming the ResultSet using StreamingOuput. I
>> convert each row in the Accept format and sent it. This way I don't have
>> anything in memory.
>>
>> But, just one question concerning copyResults and keeping the original
>> resultset. Is the original ResultSet data kept in cache? I mean the
>> whole lot of results, or just one.
> 
> The copy is a materialization of the results set plus a new array list
> to hold the bindings in.
> 
> So data is not in a cache.
> 
> You can also write code that passes algorithms from class to class and
> have the result set processing happen inside try-resource:
> 
> Argument: Consumer<ResultSet> action;
> 
> try(QueryExecution qExec = ...) {
>     action.accept(qExec.exexSelect());
> }
> 
> Java8 lambdas open up a lot of possibilities.

Here a snip of the code using begin/end methodology.

try {
        // Begin transaction
        // Launch ASK query
        // End Transaction

        // Begin transaction
        // Lauch SELECT SPARQL
        // Get resultset

        StreamingOutput stream = new StreamingOutput() {
                @Override
                public void write(OutputStream output) throws IOException,
                                                       WebApplicationException {
                        boolean aborted = false;
                        try {
                                // Stream resultset to output
                                // Therefore transaction cannot be closed
                                // till it finishes
                        } catch (Exception e) {
                                log.error("Unknown error", e);
                        } finally {
                                // End transaction
                                
                        }
                }
        };

        return rsp.entity(stream).build();
} catch (Exception ex) {
        // Close transaction in case any issue with ASK or Select
}


As you can see the main issue is with StreamingOutput as the function
returns before actually parsing the whole resultset. So I have to close
the transaction within it. I'm thinking on including the whole
functionality in the StreamingOuput and this way I can try to use Txn.
Let's see how I manage to do it. Not simple solution.

Just a final question:
Why begin/end is not behaving the same as Txn when nesting?

Thanks a lot for your help.

Regards,
Jorge

Reply via email to