public void Server()
        {
            // client.Blocking = false;
            // process the connection string
            asy = new ServerStream(client);
            var rdr = asy.rdr;
            var wtr = asy.wtr;
            int p   = -1;

            try
            {
                var fn = rdr.GetString();
                db = SDatabase.Open(path, fn);
                wtr.Write(Types.Done);
                wtr.PutLong(0);
                wtr.PutLong(0);
                asy.Flush();
            }
            catch (IOException)
            {
                asy.Close();
                return;
            }
            catch (Exception e)
            {
                try
                {
                    asy.StartException();
                    wtr.Write(Types.Exception);
                    wtr.PutString(e.Message);
                    asy.Flush();
                }
                catch (Exception) { }
                goto _return;
            }
            // start a Strong protocol service
            for (; ;)
            {
                p = -1;
                try
                {
                    p = rdr.ReadByte();
                } catch (Exception)
                {
                    p = -1;
                }
                if (p < 0)
                {
                    goto _return;
                }
                try
                {
                    //           Console.WriteLine("[" + cid + "] Start " + ((Types)p).ToString());
                    switch ((Types)p)
                    {
                    case Types.SNames:
                    {
                        var tr = db.Transact(rdr);
                        var us = db.uids;
                        for (var b = us.PositionAt(SysTable._SysUid); b != null && b.Value.Item1 < 0; b = b.Next())
                        {
                            us -= b.Value.Item1;
                        }
                        var n = rdr.GetInt();
                        for (var i = 0; i < n; i++)
                        {
                            var u = rdr.GetLong();
                            var s = rdr.GetString();
                            if (u < rdr.lastAlias)
                            {
                                rdr.lastAlias = u;
                            }
                            us += (u, s);
                        }
                        db = new STransaction(tr, new SRole(tr.role, us));
                        break;
                    }

                    case Types.DescribedGet:
                    case Types.Get:
                    {
                        var    tr = db.Transact(rdr);
                        SQuery?qy = null;
                        try
                        {
                            qy = rdr._Get() as SQuery;
                            tr = (STransaction)rdr.db;
                        } catch (Exception e)
                        {
                            rdr.buf.len = 0;
                            throw e;
                        }
                        if (qy == null)
                        {
                            throw new StrongException("Bad query");
                        }
                        qy = (SQuery)qy.Prepare(tr, qy.Names(tr, SDict <long, long> .Empty));
                        RowSet rs = qy.RowSet(tr, qy, Context.Empty);
                        var    sb = new StringBuilder("[");
                        var    cm = "";
                        for (var b = rs?.First(); b != null; b = b.Next())
                        {
                            if (((RowBookmark)b)._ob is SRow sr && sr.isValue)
                            {
                                sb.Append(cm); cm = ",";
                                sr.Append(rs._tr, sb);
                            }
                        }
                        sb.Append(']');
                        var ts = db.curpos;
                        (db, ts) = rs._tr.MaybeAutoCommit(cid);
                        wtr.Write(Types.Done);
                        wtr.PutLong(ts);
                        wtr.PutLong(db.curpos);
                        if ((Types)p == Types.DescribedGet)
                        {
                            var dp = rs._qry.Display;
                            wtr.PutInt(dp.Length ?? 0);
                            for (var b = dp.First(); b != null; b = b.Next())
                            {
                                wtr.PutString(b.Value.Item2.Item2);
                            }
                        }
                        wtr.PutString(sb.ToString());
                        asy.Flush();
                        break;
                    }

                    case Types.SCreateTable:
                    {
                        var tr = db.Transact(rdr);
                        var tn = db.role[rdr.GetLong()];        // table name
                        if (db.role.globalNames.Contains(tn))
                        {
                            throw new StrongException("Duplicate table name " + tn);
                        }
                        tr     = (STransaction)tr.Install(new STable(tr), tn, tr.curpos);
                        rdr.db = tr;
                        var n = rdr.GetInt();
                        for (var i = 0; i < n; i++)
                        {
                            CreateColumn(rdr);
                        }
                        n = rdr.GetInt();
                        for (var i = 0; i < n; i++)
                        {
                            rdr.ReadByte();
                            CreateIndex(rdr);
                        }
                        var ts = db.curpos;
                        (db, ts) = rdr.db.MaybeAutoCommit(cid);
                        wtr.Write(Types.Done);
                        wtr.PutLong(ts);
                        wtr.PutLong(db.curpos);
                        asy.Flush();
                        break;
                    }

                    case Types.SCreateColumn:
                    {
                        var tr = db.Transact(rdr);
                        rdr.db = tr;
                        CreateColumn(rdr);
                        var ts = db.curpos;
                        (db, ts) = rdr.db.MaybeAutoCommit(cid);
                        wtr.Write(Types.Done);
                        wtr.PutLong(ts);
                        wtr.PutLong(db.curpos);
                        asy.Flush();
                        break;
                    }

                    case Types.SInsert:
                    {
                        var tr = db.Transact(rdr);
                        var tn = tr.role[rdr.GetLong()];
                        if (!db.role.globalNames.Contains(tn))
                        {
                            throw new StrongException("Table " + tn + " not found");
                        }
                        var tb = (STable)db.objects[db.role.globalNames[tn]];
                        rdr.context = tb;
                        var n = rdr.GetInt();
                        var c = SList <long> .Empty;
                        for (var i = 0; i < n; i++)
                        {
                            c += (rdr.GetLong(), i);
                        }
                        var ins = new SInsert(tb.uid, c, rdr);
                        tr = ins.Prepare(tr, tb.Names(tr, SDict <long, long> .Empty)).Obey(tr, Context.Empty);
                        var ts = db.curpos;
                        (db, ts) = tr.MaybeAutoCommit(cid);
                        wtr.Write(Types.Done);
                        wtr.PutLong(ts);
                        wtr.PutLong(db.curpos);
                        asy.Flush();
                        break;
                    }

                    case Types.Insert:
                    {
                        var tr = db.Transact(rdr);
                        var tn = tr.role[rdr.GetLong()];
                        if (!db.role.globalNames.Contains(tn))
                        {
                            throw new StrongException("Table " + tn + " not found");
                        }
                        var tb = (STable)db.objects[db.role.globalNames[tn]];
                        rdr.context = tb;
                        var       n  = rdr.GetInt();  // # named cols
                        var       cs = SList <SColumn> .Empty;
                        Exception?ex = null;
                        for (var i = 0; i < n; i++)
                        {
                            var cn = db.role[rdr.GetLong()];
                            var ss = db.role.subs[tb.uid];
                            if (ss.defs.Contains(cn))
                            {
                                cs += ((SColumn)db.objects[ss.obs[ss.defs[cn]].Item1], i);
                            }
                            else
                            {
                                ex = new StrongException("Column " + cn + " not found");
                            }
                        }
                        var nc = rdr.GetInt();         // #cols
                        if ((n == 0 && nc != tb.cpos.Length) || (n != 0 && n != nc))
                        {
                            ex = new StrongException("Wrong number of columns");
                        }
                        var nr = rdr.GetInt();         // #records
                        for (var i = 0; i < nr; i++)
                        {
                            var f = SDict <long, Serialisable> .Empty;
                            if (n == 0)
                            {
                                for (var b = tb.cpos.First(); b != null; b = b.Next())
                                {
                                    if (b.Value.Item2 is SColumn sc)
                                    {
                                        f += (sc.uid, rdr._Get());
                                    }
                                }
                            }
                            else
                            {
                                for (var b = cs; b.Length != 0; b = b.next)
                                {
                                    f += (b.element.uid, rdr._Get());
                                }
                            }
                            tr = (STransaction)tr.Install(new SRecord(tr, tb.uid, f), tr.curpos);
                        }
                        if (ex != null)
                        {
                            throw ex;
                        }
                        var ts = db.curpos;
                        (db, ts) = tr.MaybeAutoCommit(cid);
                        wtr.Write(Types.Done);
                        wtr.PutLong(ts);
                        wtr.PutLong(db.curpos);
                        asy.Flush();
                        break;
                    }

                    case Types.SAlter:
                    {
                        var tr = db.Transact(asy.rdr);
                        rdr.db = tr;
                        var at = SAlter.Get(rdr);
                        tr = (STransaction)rdr.db;
                        tr = at.Prepare(tr, SDict <long, long> .Empty)
                             .Obey(tr, Context.Empty);
                        var ts = db.curpos;
                        (db, ts) = tr.MaybeAutoCommit(cid);
                        wtr.Write(Types.Done);
                        wtr.PutLong(ts);
                        wtr.PutLong(db.curpos);
                        asy.Flush();
                        break;
                    }

                    case Types.SDrop:
                    {
                        var tr = db.Transact(asy.rdr);
                        var dr = SDrop.Get(rdr).Prepare(tr, SDict <long, long> .Empty);
                        tr = dr.Obey(tr, Context.Empty);
                        var ts = db.curpos;
                        (db, ts) = tr.MaybeAutoCommit(cid);
                        wtr.Write(Types.Done);
                        wtr.PutLong(ts);
                        wtr.PutLong(db.curpos);
                        asy.Flush();
                        break;
                    }

                    case Types.SIndex:
                    {
                        var tr = db.Transact(asy.rdr);
                        rdr.db = tr;
                        CreateIndex(rdr);
                        var ts = db.curpos;
                        (db, ts) = rdr.db.MaybeAutoCommit(cid);
                        wtr.Write(Types.Done);
                        wtr.PutLong(ts);
                        wtr.PutLong(db.curpos);
                        asy.Flush();
                        break;
                    }

                    case Types.SDropIndex:
                    {
                        var tr = db.Transact(rdr);
                        rdr.db = tr;
                        var dr = new SDropIndex(rdr);
                        tr = (STransaction)rdr.db;
                        tr = dr.Prepare(tr, SDict <long, long> .Empty)
                             .Obey(tr, Context.Empty);
                        var ts = db.curpos;
                        (db, ts) = tr.MaybeAutoCommit(cid);
                        wtr.Write(Types.Done);
                        wtr.PutLong(ts);
                        wtr.PutLong(db.curpos);
                        asy.Flush();
                        break;
                    }

                    case Types.Read:
                    {
                        var id = rdr.GetLong();
                        var sb = new StringBuilder();
                        db.Get(id).Append(db, sb);
                        wtr.PutString(sb.ToString());
                        asy.Flush();
                        break;
                    }

                    case Types.SUpdateSearch:
                    {
                        var tr = db.Transact(rdr);
                        var u  = SUpdateSearch.Get(rdr);
                        tr = u.Prepare(tr, u.qry.Names(tr, SDict <long, long> .Empty)).Obey(tr, Context.Empty);
                        var ts = db.curpos;
                        (db, ts) = tr.MaybeAutoCommit(cid);
                        wtr.Write(Types.Done);
                        wtr.PutLong(ts);
                        wtr.PutLong(db.curpos);
                        asy.Flush();
                        break;
                    }

                    case Types.SUpdate:
                    {
                        var tr = db.Transact(rdr);
                        var id = rdr.GetLong();
                        var rc = db.Get(id);
                        var tb = (STable)tr.objects[rc.table];
                        var n  = rdr.GetInt();        // # cols updated
                        var f  = SDict <long, Serialisable> .Empty;
                        for (var i = 0; i < n; i++)
                        {
                            var cn = rdr.GetLong();
                            f += (cn, rdr._Get());
                        }
                        tr = (STransaction)tr.Install(new SUpdate(tr, rc, f), tr.curpos);
                        var ts = db.curpos;
                        (db, ts) = rdr.db.MaybeAutoCommit(cid);
                        wtr.Write(Types.Done);
                        wtr.PutLong(ts);
                        wtr.PutLong(db.curpos);
                        asy.Flush();
                        break;
                    }

                    case Types.SDeleteSearch:
                    {
                        var tr = db.Transact(rdr);
                        var dr = SDeleteSearch.Get(rdr);
                        tr = dr.Prepare(tr, dr.qry.Names(tr, SDict <long, long> .Empty)).Obey(tr, Context.Empty);
                        var ts = db.curpos;
                        (db, ts) = tr.MaybeAutoCommit(cid);
                        wtr.Write(Types.Done);
                        wtr.PutLong(ts);
                        wtr.PutLong(db.curpos);
                        asy.Flush();
                        break;
                    }

                    case Types.SDelete:
                    {
                        var tr = db.Transact(rdr);
                        var id = rdr.GetLong();
                        var rc = db.Get(id) as SRecord ??
                                 throw new StrongException("Record " + id + " not found");
                        tr = (STransaction)tr.Install(new SDelete(tr, rc), tr.curpos);
                        var ts = db.curpos;
                        (db, ts) = tr.MaybeAutoCommit(cid);
                        wtr.Write(Types.Done);
                        wtr.PutLong(ts);
                        wtr.PutLong(db.curpos);
                        asy.Flush();
                        break;
                    }

                    case Types.SBegin:
                        db = db.Transact(rdr, false);
                        wtr.Write(Types.Done);
                        wtr.PutLong(db.curpos);
                        wtr.PutLong(db.curpos);
                        asy.Flush();
                        break;

                    case Types.SRollback:
                        db = db.Rollback();
                        wtr.Write(Types.Done);
                        wtr.PutLong(db.curpos);
                        wtr.PutLong(db.curpos);
                        asy.Flush();
                        break;

                    case Types.SCommit:
                    {
                        var tr = db as STransaction ??
                                 throw new StrongException("No transaction to commit");
                        var ts = db.curpos;
                        (db, ts) = tr.Commit(cid);
                        wtr.Write(Types.Done);
                        wtr.PutLong(ts);
                        wtr.PutLong(db.curpos);
                        asy.Flush();
                        break;
                    }

                    default:
                        throw new StrongException("Protocol error");
                    }
                    //           Console.WriteLine("[" + cid + "] End " + ((Types)p).ToString());
                }
                catch (SocketException)
                {
                    return;
                }
                catch (StrongException e)
                {
                    try
                    {
                        db = db.Rollback();
                        //             db.result = null;
                        asy.StartException();
                        //             Console.WriteLine(""+cid+" Reporting Exception: " + e.Message);
                        wtr.Write(Types.Exception);
                        wtr.PutString(e.Message);
                        asy.Flush();
                    }
                    catch (Exception) { }
                }
                catch (Exception e)
                {
                    try
                    {
                        db = db.Rollback();
                        //             db.result = null;
                        asy.StartException();
                        //             Console.WriteLine(""+cid+" Reporting Exception: " + e.Message);
                        wtr.Write(Types.Exception);
                        wtr.PutString(e.Message);
                        asy.Flush();
                    }
                    catch (Exception) { }
                }
            }
            _return :;
        }
        public void Server()
        {
            // client.Blocking = false;
            // process the connection string
            asy = new ServerStream(client);
            var rdr = asy.rbuf;
            int p   = -1;

            try
            {
                var fn = rdr.GetString();
                db = SDatabase.Open(path, fn);
                asy.Write(Types.Done);
                asy.Flush();
            }
            catch (IOException)
            {
                asy.Close();
                return;
            }
            catch (Exception e)
            {
                try
                {
                    asy.StartException();
                    asy.Write(Types.Exception);
                    asy.PutString(e.Message);
                    asy.Flush();
                }
                catch (Exception) { }
                goto _return;
            }
            // start a Strong protocol service
            for (; ;)
            {
                p = -1;
                try
                {
                    p = rdr.ReadByte();
                } catch (Exception)
                {
                    p = -1;
                }
                if (p < 0)
                {
                    goto _return;
                }
                try
                {
                    switch ((Types)p)
                    {
                    case Types.DescribedGet:
                    case Types.Get:
                    {
                        var    tr = db.Transact();
                        SQuery?qy = null;
                        try
                        {
                            qy = rdr._Get(tr) as SQuery;
                        } catch (Exception e)
                        {
                            rdr.buf.len = 0;
                            throw e;
                        }
                        if (qy == null)
                        {
                            throw new Exception("Bad query");
                        }
                        RowSet rs = qy.RowSet(tr, qy, SDict <long, SFunction> .Empty, Context.Empty);
                        var    sb = new StringBuilder("[");
                        var    cm = "";
                        for (var b = rs?.First(); b != null; b = b.Next())
                        {
                            sb.Append(cm); cm = ",";
                            ((RowBookmark)b)._ob.Append(db, sb);
                        }
                        sb.Append(']');
                        db = db.MaybeAutoCommit(rs._tr);
                        asy.Write(Types.Done);
                        if ((Types)p == Types.DescribedGet)
                        {
                            asy.PutInt(rs._qry.Display.Length ?? 0);
                            for (var b = rs._qry.Display.First(); b != null; b = b.Next())
                            {
                                asy.PutString(b.Value.Item2);
                            }
                        }
                        asy.PutString(sb.ToString());
                        asy.Flush();
                        break;
                    }

                    case Types.SCreateTable:
                    {
                        var tr = db.Transact();
                        var tn = rdr.GetString();        // table name
                        if (tr.names.Contains(tn))
                        {
                            throw new Exception("Duplicate table name " + tn);
                        }
                        var tb = new STable(tr, tn);
                        tr = (STransaction)tr.Install(tb, tr.curpos);
                        var n = rdr.GetInt();         // #cols
                        for (var i = 0; i < n; i++)
                        {
                            var cn = rdr.GetString();         // column name
                            var dt = (Types)rdr.ReadByte();   // dataType
                            tr = (STransaction)tr.Install(new SColumn(tr, cn, dt, tb.uid), tr.curpos);
                        }
                        db = db.MaybeAutoCommit(tr);
                        asy.Write(Types.Done);
                        asy.Flush();
                        break;
                    }

                    case Types.SInsert:
                    {
                        var tr = db.Transact();
                        tr = SInsertStatement.Get(db, rdr).Obey(tr);
                        db = db.MaybeAutoCommit(tr);
                        asy.Write(Types.Done);
                        asy.Flush();
                        break;
                    }

                    case Types.Insert:
                    {
                        var       tr = db.Transact();
                        var       tb = (STable)tr.names.Lookup(rdr.GetString()); // table name
                        var       n  = rdr.GetInt();                             // # named cols
                        var       cs = SList <long> .Empty;
                        Exception?ex = null;
                        for (var i = 0; i < n; i++)
                        {
                            var cn = rdr.GetString();
                            if (tb.names.Lookup(cn) is SColumn sc)
                            {
                                cs += (sc.uid, i);
                            }
                            else
                            {
                                ex = new Exception("Column " + cn + " not found");
                            }
                        }
                        var nc = rdr.GetInt();         // #cols
                        if ((n == 0 && nc != tb.cpos.Length) || (n != 0 && n != nc))
                        {
                            throw new Exception("Wrong number of columns");
                        }
                        var nr = rdr.GetInt();         // #records
                        for (var i = 0; i < nr; i++)
                        {
                            var f = SDict <long, Serialisable> .Empty;
                            if (n == 0)
                            {
                                for (var b = tb.cpos.First(); b != null; b = b.Next())
                                {
                                    if (b.Value.Item2 is SColumn sc)
                                    {
                                        f += (sc.uid, rdr._Get(tr));         // serialisable values
                                    }
                                }
                            }
                            else
                            {
                                for (var b = cs; b.Length != 0; b = b.next)
                                {
                                    f += (b.element, rdr._Get(tr));         // serialisable values
                                }
                            }
                            tr = (STransaction)tr.Install(new SRecord(tr, tb.uid, f), tr.curpos);
                        }
                        if (ex != null)
                        {
                            throw ex;
                        }
                        db = db.MaybeAutoCommit(tr);
                        asy.Write(Types.Done);
                        asy.Flush();
                        break;
                    }

                    case Types.SAlter:
                    {
                        var tr = db.Transact();
                        var tn = rdr.GetString();         // table name
                        var tb = (STable)tr.names.Lookup(tn) ??
                                 throw new Exception("Table " + tn + " not found");
                        var cn = rdr.GetString();         // column name or ""
                        var nm = rdr.GetString();         // new name
                        if (cn.Length == 0)
                        {
                            tr = (STransaction)tr.Install(new SAlter(tr, nm, Types.STable, tb.uid, 0), tr.curpos);
                        }
                        else
                        {
                            tr = (STransaction)tr.Install(new SAlter(tr, nm, Types.SColumn, tb.uid,
                                                                     (tb.names.Lookup(cn) is SColumn sc) ? sc.uid :
                                                                     throw new Exception("Column " + cn + " not found")), tr.curpos);
                        }
                        db = db.MaybeAutoCommit(tr);
                        asy.Write(Types.Done);
                        asy.Flush();
                        break;
                    }

                    case Types.SDrop:
                    {
                        var tr = db.Transact();
                        var nm = rdr.GetString();         // object name
                        var pt = tr.names.Lookup(nm) ??
                                 throw new Exception("Object " + nm + " not found");
                        var cn = rdr.GetString();
                        tr = (STransaction)tr.Install(
                            (cn.Length == 0) ?
                            new SDrop(tr, pt.uid, -1) :
                            new SDrop(tr,
                                      (((STable)pt).names.Lookup(cn) is SColumn sc) ? sc.uid :
                                      throw new Exception("Column " + cn + " not found"),
                                      pt.uid), tr.curpos);
                        db = db.MaybeAutoCommit(tr);
                        asy.Write(Types.Done);
                        asy.Flush();
                        break;
                    }

                    case Types.SCreateIndex:
                    {
                        var tr = db.Transact();
                        var tn = rdr.GetString();         // table name
                        var tb = (STable)tr.names.Lookup(tn) ??
                                 throw new Exception("Table " + tn + " not found");
                        var xt = rdr.ReadByte();
                        var rn = rdr.GetString();
                        var ru = (rn.Length == 0)?-1: (tr.names.Lookup(rn)?.uid ??
                                                       throw new Exception("Table " + tn + " not found"));
                        var nc = rdr.GetInt();
                        var cs = SList <long> .Empty;
                        for (var i = 0; i < nc; i++)
                        {
                            var cn = rdr.GetString();
                            var se = (tb.names.Lookup(cn) is SColumn sc)? sc.uid :
                                     throw new Exception("Column " + cn + " not found");
                            cs += (se, i);
                        }
                        tr = (STransaction)tr.Install(new SIndex(tr, tb.uid, xt < 2, ru, cs), tr.curpos);
                        db = db.MaybeAutoCommit(tr);
                        asy.Write(Types.Done);
                        asy.Flush();
                        break;
                    }

                    case Types.Read:
                    {
                        var id = rdr.GetLong();
                        var sb = new StringBuilder();
                        db.Get(id).Append(db, sb);
                        asy.PutString(sb.ToString());
                        asy.Flush();
                        break;
                    }

                    case Types.SUpdateSearch:
                    {
                        var tr = db.Transact();
                        tr = SUpdateSearch.Get(db, rdr).Obey(tr, Context.Empty);
                        db = db.MaybeAutoCommit(tr);
                        asy.Write(Types.Done);
                        asy.Flush();
                        break;
                    }

                    case Types.SUpdate:
                    {
                        var tr = db.Transact();
                        var id = rdr.GetLong();
                        var rc = db.Get(id);
                        var tb = (STable)tr.objects[rc.table];
                        var n  = rdr.GetInt();        // # cols updated
                        var f  = SDict <string, Serialisable> .Empty;
                        for (var i = 0; i < n; i++)
                        {
                            var cn = rdr.GetString();
                            f += (cn, rdr._Get(db));
                        }
                        tr = (STransaction)tr.Install(new SUpdate(tr, rc, f), tr.curpos);
                        db = db.MaybeAutoCommit(tr);
                        asy.Write(Types.Done);
                        asy.Flush();
                        break;
                    }

                    case Types.SDeleteSearch:
                    {
                        var tr = db.Transact();
                        tr = SDeleteSearch.Get(db, rdr).Obey(tr, Context.Empty);
                        db = db.MaybeAutoCommit(tr);
                        asy.Write(Types.Done);
                        asy.Flush();
                        break;
                    }

                    case Types.SDelete:
                    {
                        var tr = db.Transact();
                        var id = rdr.GetLong();
                        var rc = db.Get(id) as SRecord ??
                                 throw new Exception("Record " + id + " not found");
                        tr = (STransaction)tr.Install(new SDelete(tr, rc.table, rc.uid), tr.curpos);
                        db = db.MaybeAutoCommit(tr);
                        asy.Write(Types.Done);
                        asy.Flush();
                        break;
                    }

                    case Types.SBegin:
                        db = new STransaction(db, false);
                        asy.WriteByte((byte)Types.Done);
                        asy.Flush();
                        break;

                    case Types.SRollback:
                        db = db.Rollback();
                        asy.WriteByte((byte)Types.Done);
                        asy.Flush();
                        break;

                    case Types.SCommit:
                    {
                        var tr = db as STransaction ??
                                 throw new Exception("No transaction to commit");
                        db = tr.Commit();
                        asy.WriteByte((byte)Types.Done);
                        asy.Flush();
                        break;
                    }

                    default:
                        throw new Exception("Protocol error");
                    }
                }
                catch (SocketException)
                {
                    return;
                }
                catch (Exception e)
                {
                    try
                    {
                        db = db.Rollback();
                        //             db.result = null;
                        asy.StartException();
                        asy.Write(Types.Exception);
                        asy.PutString(e.Message);
                        asy.Flush();
                    }
                    catch (Exception) { }
                }
            }
            _return :;
        }