Example #1
0
File: ses.go Project: rjammala/ora
// 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
}
Example #2
0
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
}
Example #3
0
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
}
Example #4
0
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
}
Example #5
0
// 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
}