Straight mapping of OCI transaction functions to ruby-oci8
@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:
ruby 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;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 byOCIHandleAlloc(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 ofOCI8::Xid, to the OCI_ATTR_XID attribute#xid- gets the OCI_ATTR_XID attribute asOCI8::Xid
-
OCI8- connection-
#trans_handle=handle- sets the transaction handle It corresponds toOCIAttrSet(svchp, OCI_HTYPE_SVCCTX, txnhp, 0, OCI_ATTR_TRANS, errhp). The handle is set to@trans_handleinstance variable ofselfalso 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_phaseOCI_TRANS_TWOPHASE:write_immediateOCI_TRANS_WRITEIMMED:write_batchOCI_TRANS_WRITEBATCH:write_waitOCI_TRANS_WRITEWAIT:write_no_waitOCI_TRANS_WRITENOWAITconn.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 returnstruewhen the transaction must be committed byconn.commit(:two_phase).falsewhenORA-24767: transaction branch prepare returns read-only. -
#trans_start(timeout, flag...)- calls OCITransStart. Flags are specified by symbol.ruby symbol OCI constant :newOCI_TRANS_NEW:tightOCI_TRANS_TIGHT:looseOCI_TRANS_LOOSE:resumeOCI_TRANS_RESUME:readonlyOCI_TRANS_READONLY:serializableOCI_TRANS_SERIALIZABLEconn.trans_start(10, :new) # OCI_TRANS_NEW ... conn.trans_start(10, :new, :tight ) # OCI_TRANS_NEW | OCI_TRANS_TIGHT
-
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.
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 send me email with questions about XA and I will find answers.