// StartTx starts an Oracle transaction returning a *Tx and possible error. func (ses *Ses) StartTx() (tx *Tx, err error) { ses.mu.Lock() defer ses.mu.Unlock() ses.log(_drv.cfg.Log.Ses.StartTx) err = ses.checkClosed() if err != nil { return nil, errE(err) } // start transaction // the number of seconds the transaction can be inactive // before it is automatically terminated by the system. // TODO: add timeout config value var timeout C.uword = C.uword(60) r := C.OCITransStart( ses.srv.ocisvcctx, //OCISvcCtx *svchp, ses.srv.env.ocierr, //OCIError *errhp, timeout, //uword timeout, C.OCI_TRANS_NEW) //ub4 flags ); if r == C.OCI_ERROR { return nil, errE(ses.srv.env.ociError()) } tx = _drv.txPool.Get().(*Tx) // set *Tx tx.ses = ses if tx.id == 0 { tx.id = _drv.txId.nextId() } ses.openTxs.add(tx) return tx, nil }
func (c *OCI8Conn) Begin() (driver.Tx, error) { if c.transactionMode != C.OCI_TRANS_READWRITE { var th unsafe.Pointer if rv := C.WrapOCIHandleAlloc( c.env, C.OCI_HTYPE_TRANS, 0); rv.rv != C.OCI_SUCCESS { return nil, errors.New("can't allocate handle") } else { th = rv.ptr } if rv := C.OCIAttrSet( c.svc, C.OCI_HTYPE_SVCCTX, th, 0, C.OCI_ATTR_TRANS, (*C.OCIError)(c.err)); rv != C.OCI_SUCCESS { return nil, ociGetError(c.err) } if rv := C.OCITransStart( (*C.OCISvcCtx)(c.svc), (*C.OCIError)(c.err), 0, c.transactionMode); // C.OCI_TRANS_SERIALIZABLE C.OCI_TRANS_READWRITE C.OCI_TRANS_READONLY rv != C.OCI_SUCCESS { return nil, ociGetError(c.err) } } c.inTransaction = true return &OCI8Tx{c}, nil }
func (conn *OCI8Conn) Begin() (driver.Tx, error) { if conn.inTx { return nil, errors.New("transaction already in progress") } var txHandle unsafe.Pointer // determine if a transaction handle was previously allocated rv := C.OCIAttrGet( conn.svc, C.OCI_HTYPE_SVCCTX, unsafe.Pointer(&txHandle), nil, C.OCI_ATTR_TRANS, (*C.OCIError)(conn.err), ) if err := conn.check(rv, "OCI8Conn.Begin() find existing transaction handle"); err != nil { return nil, err } if txHandle == nil { rv := C.OCIHandleAlloc( conn.env, &txHandle, C.OCI_HTYPE_TRANS, 0, nil, ) if err := conn.check(rv, "OCI8Conn.Begin() allocate transaction handle"); err != nil { return nil, err } } rv = C.OCIAttrSet( conn.svc, C.OCI_HTYPE_SVCCTX, txHandle, 0, C.OCI_ATTR_TRANS, (*C.OCIError)(conn.err), ) if err := conn.check(rv, "OCI8Conn.Begin(): associate transaction"); err != nil { return nil, err } rv = C.OCITransStart( (*C.OCISvcCtx)(conn.svc), (*C.OCIError)(conn.err), 60, C.OCI_TRANS_NEW, ) if err := conn.check(rv, "OCI8Conn.Begin(): start transaction"); err != nil { return nil, err } conn.inTx = true return conn, nil }
func (c *OCI8Conn) Begin() (driver.Tx, error) { rv := C.OCITransStart( (*C.OCISvcCtx)(c.svc), (*C.OCIError)(c.err), 60, C.OCI_TRANS_NEW) if rv == C.OCI_ERROR { return nil, ociGetError(c.err) } return &OCI8Tx{c}, nil }
// Begin begins a new transaction on the connection. func (conn *Connection) Begin(formatID int, transactionID, branchID string) error { var transactionHandle *C.OCITrans var xid C.XID // parse the arguments formatID = -1 if len(transactionID) > C.MAXGTRIDSIZE { return errors.New("transaction id too large") } if len(branchID) > C.MAXBQUALSIZE { return errors.New("branch id too large") } // make sure we are actually connected if !conn.IsConnected() { return nil } // determine if a transaction handle was previously allocated _, err := conn.environment.AttrGet( unsafe.Pointer(conn.handle), C.OCI_HTYPE_SVCCTX, C.OCI_ATTR_TRANS, unsafe.Pointer(&transactionHandle), "Connection.Begin(): find existing transaction handle") if err != nil { return err } // create a new transaction handle, if necessary if transactionHandle == nil { if err = ociHandleAlloc(unsafe.Pointer(conn.environment.handle), C.OCI_HTYPE_TRANS, (*unsafe.Pointer)(unsafe.Pointer(&transactionHandle)), "Connection.Begin"); err != nil { return errors.New("Connection.Begin(): allocate transaction handle: " + err.Error()) } } // set the XID for the transaction, if applicable if formatID != -1 { tID := []byte(transactionID) bID := []byte(branchID) C.setXID(&xid, C.int(formatID), (*C.char)(unsafe.Pointer(&tID[0])), C.int(len(tID)), (*C.char)(unsafe.Pointer(&bID[0])), C.int(len(bID))) if err = conn.environment.AttrSet( unsafe.Pointer(transactionHandle), C.OCI_ATTR_XID, C.OCI_HTYPE_TRANS, unsafe.Pointer(&xid), C.sizeof_XID); err != nil { return errors.New("Connection.Begin(): set XID: " + err.Error()) } } // associate the transaction with the connection if err = conn.environment.AttrSet( unsafe.Pointer(conn.handle), C.OCI_HTYPE_SVCCTX, C.OCI_ATTR_TRANS, unsafe.Pointer(transactionHandle), 0); err != nil { return errors.New("Connection.Begin(): associate transaction: " + err.Error()) } // start the transaction //Py_BEGIN_ALLOW_THREADS conn.srvMtx.Lock() err = conn.environment.CheckStatus( C.OCITransStart(conn.handle, conn.environment.errorHandle, 0, C.OCI_TRANS_NEW), "start transaction") conn.srvMtx.Unlock() if err != nil { return errors.New("Connection.Begin(): start transaction: " + err.Error()) } //Py_END_ALLOW_THREADS return nil }