예제 #1
0
        public void BeginTransaction(TransactionParameterBuffer tpb)
        {
            lock (this.db)
            {
                if (this.state != TransactionState.NoTransaction)
                {
                    throw new IscException(
                              IscCodes.isc_arg_gds,
                              IscCodes.isc_tra_state,
                              this.handle,
                              "no valid");
                }

                IscTeb teb     = new IscTeb();
                IntPtr tebData = IntPtr.Zero;

                try
                {
                    this.state = TransactionState.TrasactionStarting;

                    // Set db handle
                    teb.dbb_ptr = Marshal.AllocHGlobal(4);
                    Marshal.WriteInt32(teb.dbb_ptr, this.db.Handle);

                    // Set tpb length
                    teb.tpb_len = tpb.Length;

                    // Set TPB data
                    teb.tpb_ptr = Marshal.AllocHGlobal(tpb.Length);
                    Marshal.Copy(tpb.ToArray(), 0, teb.tpb_ptr, tpb.Length);

                    // Alloc memory	for	the	IscTeb structure
                    int size = Marshal.SizeOf(typeof(IscTeb));
                    tebData = Marshal.AllocHGlobal(size);

                    Marshal.StructureToPtr(teb, tebData, true);

                    int[] statusVector = FesConnection.GetNewStatusVector();
                    int   trHandle     = this.handle;

                    FbClient.isc_start_multiple(
                        statusVector,
                        ref trHandle,
                        1,
                        tebData);

                    this.handle = trHandle;

                    // Parse status	vector
                    this.db.ParseStatusVector(statusVector);

                    // Update transaction state
                    this.state = TransactionState.TransactionStarted;

                    // Update transaction count
                    this.db.TransactionCount++;
                }
                catch (Exception)
                {
                    throw;
                }
                finally
                {
                    // Free	memory
                    if (teb.dbb_ptr != IntPtr.Zero)
                    {
                        Marshal.FreeHGlobal(teb.dbb_ptr);
                    }
                    if (teb.tpb_ptr != IntPtr.Zero)
                    {
                        Marshal.FreeHGlobal(teb.tpb_ptr);
                    }
                    if (tebData != IntPtr.Zero)
                    {
                        Marshal.DestroyStructure(tebData, typeof(IscTeb));
                        Marshal.FreeHGlobal(tebData);
                    }
                }
            }
        }