当前位置:编程学习 > C#/ASP.NET >>

小弟刚学写事务,不知道哪出错了,高手来指点一下!

/// <summary>
        /// 添加项目科目信息
        /// </summary>
        /// <param name="ps">项目科目实体</param>
        /// <returns>bool</returns>
        public bool add(int proj)
        {
            //查询所有的科目
            DocSubjectDAL dsd = new DocSubjectDAL();
            List<DocSubject> dsList = dsd.getAllSubject();
            //声明一个事务
            OleDbTransaction trans = app.DBE.Connection.BeginTransaction();
            bool flag = false;
            try
            {
                //添加项目科目数据为科目集合数
                for (int i = 0; i < dsList.Count; i++)
                {
                    string sql = "insert into cfd_project_projectsubject values (CFD_PROJECT_PROJECTSUBJECT_SEQ.Nextval," +
                        proj + "," + dsList[i].Id + "," + dsList[i].agencyId + ",0)";
                    flag = app.DBE.ExecNonQuery(sql);
                    if (flag == false)
                    {
                        trans.Rollback();            //如果没有正确执行就返回
                        break;
                    }
                }
                trans.Commit();                 //都成功,提交
            }
            catch
            {
                trans.Rollback();            
                throw;
            }

            return flag;
        }
--------------------编程问答-------------------- 什麽錯啊? --------------------编程问答-------------------- 错误信息:
“/”应用程序中的服务器错误。
--------------------------------------------------------------------------------

此 OleDbTransaction 已完成;它再也无法使用。 
说明: 执行当前 Web 请求期间,出现未处理的异常。请检查堆栈跟踪信息,以了解有关该错误以及代码中导致错误的出处的详细信息。 

异常详细信息: System.InvalidOperationException: 此 OleDbTransaction 已完成;它再也无法使用。

源错误: 


行 53:             catch
行 54:             {
行 55:                 trans.Rollback();            
行 56:                 throw;
行 57:             }
 

源文件: C:\Documents and Settings\CFD\桌面\project\SZCS-CFD\DAL\Project\ProjectSubjectDAL.cs    行: 55 

堆栈跟踪: 


[InvalidOperationException: 此 OleDbTransaction 已完成;它再也无法使用。]
   System.Data.OleDb.OleDbTransaction.Rollback() +99
   DAL.Project.ProjectSubjectDAL.add(Int32 proj) in C:\Documents and Settings\CFD\桌面\project\SZCS-CFD\DAL\Project\ProjectSubjectDAL.cs:55
   DAL.Project.ProjectSubjectDAL.getPSByProjectid(Int32 proj) in C:\Documents and Settings\CFD\桌面\project\SZCS-CFD\DAL\Project\ProjectSubjectDAL.cs:128
   BLL.Project.ProjectSubjectBLL.getPSByProjectid(Int32 projectid) in C:\Documents and Settings\CFD\桌面\project\SZCS-CFD\BLL\Project\ProjectSubjectBLL.cs:31

[TargetInvocationException: 调用的目标发生了异常。]
   System.RuntimeMethodHandle._InvokeMethodFast(Object target, Object[] arguments, SignatureStruct& sig, MethodAttributes methodAttributes, RuntimeTypeHandle typeOwner) +0
   System.RuntimeMethodHandle.InvokeMethodFast(Object target, Object[] arguments, Signature sig, MethodAttributes methodAttributes, RuntimeTypeHandle typeOwner) +72
   System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, Boolean skipVisibilityChecks) +358
   System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) +29
   System.Web.UI.WebControls.ObjectDataSourceView.InvokeMethod(ObjectDataSourceMethod method, Boolean disposeInstance, Object& instance) +480
   System.Web.UI.WebControls.ObjectDataSourceView.ExecuteSelect(DataSourceSelectArguments arguments) +1960
   System.Web.UI.DataSourceView.Select(DataSourceSelectArguments arguments, DataSourceViewSelectCallback callback) +17
   System.Web.UI.WebControls.DataBoundControl.PerformSelect() +149
   System.Web.UI.WebControls.BaseDataBoundControl.DataBind() +70
   System.Web.UI.WebControls.GridView.DataBind() +4
   System.Web.UI.WebControls.BaseDataBoundControl.EnsureDataBound() +82
   System.Web.UI.WebControls.CompositeDataBoundControl.CreateChildControls() +69
   System.Web.UI.Control.EnsureChildControls() +87
   System.Web.UI.Control.PreRenderRecursiveInternal() +41
   System.Web.UI.Control.PreRenderRecursiveInternal() +161
   System.Web.UI.Control.PreRenderRecursiveInternal() +161
   System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +1360

 


--------------------------------------------------------------------------------
版本信息: Microsoft .NET Framework 版本:2.0.50727.1891; ASP.NET 版本:2.0.50727.1879  --------------------编程问答-------------------- if (flag == false)
                    {
                        trans.Rollback();            //如果没有正确执行就返回
                        break;
                    }

这里 flag ==false rollback();

执行到 commit 报错 --------------------编程问答-------------------- 事务 rollback 或者 commit 后不能再操作 --------------------编程问答-------------------- 1、执行事务前需要打开数据库连接
2、需要指定SqlCommand.Transaction=tran;
3、跳出for循环后会继续执行trans.Commit(); //都成功,提交
   这里是会出错的,因为前面可能已经Rollback了,可以修改为以下代码:

if (flag == false)
{
 trans.Rollback();            //如果没有正确执行就返回
 //Log.Error("add failed: " + flag.ToString());
 throw new Exception("add failed!");
 return;
}

--------------------编程问答-------------------- 修改一下:

if (flag == false)
{
 //trans.Rollback();            //如果没有正确执行就返回,这句需要注释掉
 //Log.Error("add failed: " + flag.ToString()); //记录错误日志
 throw new Exception("add failed!");
 return;
}
--------------------编程问答-------------------- 再改一下:
if (flag == false)
{
 //trans.Rollback();            //如果没有正确执行就返回,这句需要注释掉
 //Log.Error("add failed: " + flag.ToString()); //记录错误日志
 throw new Exception("add failed!");
 //return;抛出异常后会直接跳转到catch代码块
}

6楼回复是错的。 --------------------编程问答-------------------- 这样暴力破解,就只有撞大运了。开多线程也许会快点 --------------------编程问答-------------------- 你定义一个事务,请把你的sql语句,拼接成一个长的sql执行,比如 insert ............;insert...........;............... --------------------编程问答-------------------- 不行啊,那个科目是动态生成的,要用几个insert语句我也不能确定。
引用 9 楼 chen_ya_ping 的回复:
你定义一个事务,请把你的sql语句,拼接成一个长的sql执行,比如 insert ............;insert...........;...............
--------------------编程问答-------------------- - -,还是报相同的错误,但是数据库里面确实是添加了信息。
引用 7 楼 dsjoy 的回复:
再改一下:

C# code

if (flag == false)
{
 //trans.Rollback();            //如果没有正确执行就返回,这句需要注释掉
 //Log.Error("add failed: " + flag.ToString()); //记录错误日志
 throw new Exception("add failed!");
 //ret……
--------------------编程问答-------------------- break换成return false --------------------编程问答-------------------- 我刚才调试  if (flag == false)  
这并没有进去,就是flag都是true
并且都正确执行了
然后他commit了
然后就进catch了,- -
我调试的时候看trans.Commit(); 里的trans里的connection是为null,但是我在这个类的最上面就声明了连接字符串
AppData app = AppData.GetInstance();     //声明一个数据库操作对象
        OleDbDataReader reader;
,难道用trans的时候还要在声明一次?连接字符串不是声明一次就够了? --------------------编程问答--------------------
引用 11 楼 suoguoen 的回复:
- -,还是报相同的错误,但是数据库里面确实是添加了信息。

引用 7 楼 dsjoy 的回复:
再改一下:

C# code

if (flag == false)
{
//trans.Rollback(); //如果没有正确执行就返回,这句需要注释掉
//Log.Error("add failed: " + flag.ToString()); //记录错误日志
throw……

肯定会报错了,因为flag ==  false的时候抛出了一个异常,你可以把catch里的throw去掉试试 --------------------编程问答--------------------
开启事务之前,你要先给SqlCommand指点连接,
app.DBE.Connection.BeginTransaction();并没有给sqlCommand指定连接呀,你先给sqlCommand指点连接,在指点事务,试试看! --------------------编程问答--------------------
        /// <summary>
        /// 添加项目科目信息
        /// </summary>
        /// <param name="ps">项目科目实体</param>
        /// <returns>bool</returns>
        public bool add(int proj)
        {
            //查询所有的科目
            DocSubjectDAL dsd = new DocSubjectDAL();
            List<DocSubject> dsList = dsd.getAllSubject();    
            //指点连接
            OleDbConnection conn = app.DBE.Connection;
            //声明一个事务
            OleDbTransaction trans = conn.BeginTransaction();
            //执行对象
            OleDbCommand cmd = new OleDbCommand();

            bool flag = false;
            try
            {
                    cmd.Transaction = trans;
                    //添加项目科目数据为科目集合数
                    for (int i = 0; i < dsList.Count; i++)
                    {
                        string sql = "insert into cfd_project_projectsubject values (CFD_PROJECT_PROJECTSUBJECT_SEQ.Nextval," +
                            proj + "," + dsList[i].Id + "," + dsList[i].agencyId + ",0)";
                        flag = app.DBE.ExecNonQuery(sql);
                        if (flag == false)
                        {
                            throw new Exception("add failed!");
                        }
                    }
                    trans.Commit();                 //都成功,提交
            }
            catch
            {
                trans.Rollback();            
                throw;
            }

            return flag;
        }
指点连接了,还是报一样的错误啊!
引用 15 楼 huangmeimujin 的回复:
开启事务之前,你要先给SqlCommand指点连接,
app.DBE.Connection.BeginTransaction();并没有给sqlCommand指定连接呀,你先给sqlCommand指点连接,在指点事务,试试看!
补充:.NET技术 ,  ASP.NET
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,