ruby-oci8 icon indicating copy to clipboard operation
ruby-oci8 copied to clipboard

Straight mapping of OCI transaction functions to ruby-oci8

Open kubo opened this issue 6 years ago • 3 comments

@tomasjura This is a one-to-one mapping. I won't merge it because it isn't easy-to-use and some methods' usages are obscure for me.

The following classes and methods are added.

  • OCI8::Xid - a mapping of XID structure defined in xa.h.

    • #new(format_id, gtrid, bqual) - creates a new Xid instance using format id, global transaction id and branch qualifier. C code:
      /* start a transaction with global transaction id = [1000, 123, 1] */
      gxid.formatID = 1000; /* format id = 1000 */
      gxid.gtrid_length = 3; /* gtrid = 123 */
      gxid.data[0] = 1; gxid.data[1] = 2; gxid.data[2] = 3;
      gxid.bqual_length = 1; /* bqual = 1 */
      gxid.data[3] = 1;
      
      ruby code:
      xid = OCI8::Xid.new(1000, "\x01\x02\x03", "\x01")
      
    • #format_id - gets format id as Integer.
    • #gtrid - gets global transaction id as ASCII-8bit String.
    • #bqual - gets branch qualifier as ASCII-8bit String.
  • OCI8::TransHandle - a mapping of transaction handle.

    • #new - creates a new transaction handle by OCIHandleAlloc(envhp, (void **)&handle, OCI_HTYPE_TRANS, 0, 0)
    • #name=string - sets the string value to the OCI_ATTR_TRANS_NAME attribute.
    • #name - gets the OCI_ATTR_TRANS_NAME attribute. As far as I checked, it seems same with #xid.gtrid
    • #timeout=integer- sets the integer value to the OCI_ATTR_TRANS_TIMEOUT attrbiute.
    • #timeout- gets the OCI_ATTR_TRANS_TIMEOUT attrbiute.
    • #xid=xid - sets the xid value, which must be an instance of OCI8::Xid, to the OCI_ATTR_XID attribute
    • #xid - gets the OCI_ATTR_XID attribute as OCI8::Xid
  • OCI8 - connection

    • #trans_handle=handle - sets the transaction handle It corresponds to OCIAttrSet(svchp, OCI_HTYPE_SVCCTX, txnhp, 0, OCI_ATTR_TRANS, errhp). The handle is set to @trans_handle instance variable of self also in order to prevent it from being freed by GC.

    • #trans_handle - gets the transaction handle set by #trans_handle=.

    • #commit(flag...) - calls OCITransCommit. Flags are specified by symbol.

      ruby symbol OCI constant
      :two_phase OCI_TRANS_TWOPHASE
      :write_immediate OCI_TRANS_WRITEIMMED
      :write_batch OCI_TRANS_WRITEBATCH
      :write_wait OCI_TRANS_WRITEWAIT
      :write_no_wait OCI_TRANS_WRITENOWAIT
      conn.commit   # no flags are specified.
      ...
      conn.commit(:two_phase) # OCI_TRANS_TWOPHASE
      
    • #trans_detach - calls OCITransDetach.

    • #trans_forget - calls OCITransForget.

    • #trans_prepare - calls OCITransPrepare. It returns true when the transaction must be committed by conn.commit(:two_phase). false when ORA-24767: transaction branch prepare returns read-only.

    • #trans_start(timeout, flag...) - calls OCITransStart. Flags are specified by symbol.

      ruby symbol OCI constant
      :new OCI_TRANS_NEW
      :tight OCI_TRANS_TIGHT
      :loose OCI_TRANS_LOOSE
      :resume OCI_TRANS_RESUME
      :readonly OCI_TRANS_READONLY
      :serializable OCI_TRANS_SERIALIZABLE
      conn.trans_start(10, :new) # OCI_TRANS_NEW
      ...
      conn.trans_start(10, :new, :tight ) # OCI_TRANS_NEW | OCI_TRANS_TIGHT
      

kubo avatar Apr 29 '19 13:04 kubo

Wow, thank you. You are very quick and productive. I haven't finished feasibility of XA transaction on the second resource manager - MQ server ( https://github.com/reidmorrison/rubywmq ) in Ruby and you are finished with OCI. I will pull, study and test your XA improvements.

tomasjura avatar Apr 29 '19 21:04 tomasjura

This is just a draft. It is a first step to learn the usage and find more usable methods. I may remove OCI8::Xid and OCI8::TransHandle later.

Start a global transaction using the current draft methods:

txn = OCI8::TransHandle.new()
txn.xid = OCI8::Xid.new(1000, "\x01\x02\x03", "\x01")
conn.trans_handle = txn
conn.trans_start(90, :new)

This may be changed as follows:

conn.trans_start([1000, "\x01\x02\x03", "\x01"], timeout: 90)

TransHandle is allocated internally. Xid is specified by an array or any object which has format_id, gtrid and bqual methods. timeout: is optional because it is required only when trans_detach() is called later and I guess that almost users don't need it.

kubo avatar Apr 30 '19 00:04 kubo

@kubo send me email with questions about XA and I will find answers.

cjbj avatar Jun 04 '19 06:06 cjbj