[ 
https://issues.apache.org/jira/browse/HBASE-11447?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=14087056#comment-14087056
 ] 

Gary Helmling commented on HBASE-11447:
---------------------------------------

Reading through the latest proposal (v0.5) I had a couple high level questions 
about what our goals for this are:

# What are we aiming for with this: zero code change when switching between 
implementations or minimal code change (implementation specific classes are 
still referenced / instantiated)?  I think this is important in guiding how 
user code selects the transaction implementation that it wants to work with and 
how we expose any implementation-specific features.
# How do you obtain an instance of: TransactionService, Transaction, 
TransactionTable?  The proposal needs to provide clarity on this.  The examples 
section currently just shows instantiating the abstract classes directly, which 
won't work as-is.  Are clients expected to instantiate the implementation 
specific classes directly or do we plan to provide some factories to abstract 
the specific class away?
# I think all of the core constructs should opt more for interfaces than 
abstract classes.  I'm not really seeing any commonality of implementations 
other than the contract that we're trying to enforce.


Some more specific comments on individual areas of the proposal:

*TransactionStatus*

We make use of an additional INVALID status as well.  How do we make these 
status extensible for different implementations?  PREPARED and PREPARING don't 
apply to us also, since we don't use 2pc.


*TransactionIsolationLevel*

I know that you are planning to add snapshot isolation as well, but I'm 
actually wondering if this is needed yet?  Would this currently be used or are 
we future-proofing?  How many of the current transaction implementations 
actually support selectable isolation levels at the moment?


*TransactionService*

* I mentioned this above in general questions, but is the intent that a 
subclass of this would be instantiated directly by the client?  This also seems 
more like it should be an interface to me as I don't think there's likely to be 
much commonality between implementations.
* The ability to change the default settings at any time (setIsolationLevel, 
setTransactionType, setTransactionTimeout) seems messy if an instance is used 
in a multi-threaded context.  Maybe these belong in a Builder interface 
instead, so the defaults are then fixed for a given instance.


*Transaction*

Is the transaction "started" when it's constructed?  For some implementations, 
"starting" might not even be a requirement, but for Tephra it's part of the 
transaction lifecycle.  This involves doing RPC to start a transaction, which I 
don't believe we should be doing in a constructor.  From my perspective at 
least, it might make more sense if, instead of being constructed directly, the 
{{Transaction}} was obtained via a factory method on {{TransactionService}} 
(say {{start()}}).


*TransactionTable*

The current recommended client API for obtaining {{HTableInterface}} instances 
is, I believe, to use one of the {{HConnection.getTable()}} variants.  How can 
we make this work with that approach?  For Tephra, we punted on this by 
providing a {{TransactionAwareHTable}} that you construct with an underlying 
{{HTable}} instance to use, but I recognize that other implementors might have 
different needs.


*3.7 Configuration*

{{hbase.transaction.transactionservice}} is configurable but it is not clear 
how this is used in instantiation.

*5. Examples*

It would be useful to illustrate some of the code for error handling here.


Tephra makes use of similar abstractions for the client API, with one addition:
* {{TransactionServiceClient}}, which handles interactions with the transaction 
manager, though for normal usage the client does not invoke it directly
* {{TransactionContext}}, which coordinates the transaction lifecycle 
operations with the transaction manager and the transaction participants.  This 
is the main class used by clients.
* {{TransactionAware}}, an interface that provides the contract for transaction 
participants.  The main implementation that would be used by HBase clients is 
{{TransactionAwareHTable}}.  This allows some extensibility to plugin other 
systems as well.


To better clarify the usage, I'll update the first example from section 5.1.1 
with how it might use the current Tephra classes:

{code}
Configuration config = HBaseConfiguration.create();
HConnection conn = HConnectionManager.createConnection(config);

TransactionServiceClient client = new TransactionServiceClient(config, ...);
TransactionAwareHTable txTable = new TransactionAwareHTable(
    conn.getTable(TableName.valueOf("table1")));

TransactionContext txContext = new TransactionContext(client, txTable);
try {
    // begin new transaction
    txContext.start();

    Put p1 = new Put(Bytes.toBytes("row1"));
    p1.add(Bytes.toBytes("cf"), Bytes.toBytes("q"), Bytes.toBytes("value1"));
    txTable.put(p1);
 
    Put p2 = new Put(Bytes.toBytes("row2"));
    p2.add(Bytes.toBytes("cf"), Bytes.toBytes("q"), Bytes.toBytes("value2"));
    txTable.put(p2);

    txContext.finish();
} catch (TransactionFailureException e) {
    txContext.abort();
}
{code}


{{TransactionServiceClient}} maps to {{TransactionService}} in the proposal, 
though most operations would be implementation specific.  
{{TransactionContext}} is not too far off from what you have as {{Transaction}} 
in the proposal, with the addition of a {{start()}} method and the ability to 
use it multiple times.  And {{TransactionAware}}, while not typically used 
directly by clients, allows the coordination of transaction manager and HBase 
operations to be abstracted away from the client code.

So I don't think there is much of a gap for us in the core abstractions, but as 
you can see in the example there is a lot of implementation specific 
construction going on.  Is the idea to abstract this away as well?

> Proposal for a generic transaction API for HBase
> ------------------------------------------------
>
>                 Key: HBASE-11447
>                 URL: https://issues.apache.org/jira/browse/HBASE-11447
>             Project: HBase
>          Issue Type: New Feature
>          Components: Client
>    Affects Versions: 1.0.0
>         Environment: Any.
>            Reporter: John de Roo
>            Priority: Minor
>              Labels: beginner
>             Fix For: 1.0.0
>
>         Attachments: Proposal for a common transactional API for HBase 
> v0.3_1.pdf, Proposal for a common transactional API for HBase v0.4_1.pdf, 
> Proposal for a common transactional API for HBase v0.5.pdf, Re Proposal for a 
> generic transaction API for HBase.htm
>
>
> HBase transaction management today is provided by a number of products, each 
> implementing a different API, each having different strengths.  The lack of a 
> common API for transactional interfaces means that applications need to be 
> coded to work with a specific Transaction Manager.  This proposal outlines an 
> API which, if implemented by the different Transaction Manager vendors would 
> provide stability and choice to HBase application developers.  



--
This message was sent by Atlassian JIRA
(v6.2#6252)

Reply via email to