首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > .NET > .NET >

急 程序中在执行一段代码的时候数据库出现死锁,

2012-12-14 
急,高手请进,!! 程序中在执行一段代码的时候数据库出现死锁,。本帖最后由 mr_cheung 于 2011-10-23 21:47:5

急,高手请进,!! 程序中在执行一段代码的时候数据库出现死锁,。
本帖最后由 mr_cheung 于 2011-10-23 21:47:54 编辑 C# 在查询某条数据时出现死锁,超时情况。
一下是查询数据库方法 C#代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.SqlClient;
using System.Data;

namespace WindowsFormsApplication1
{
    class DBHelpSQL
    {
        static string stsqlcon = "Data Source=10.2.103.10;Initial Catalog=Testhis;User ID=sa";
        //static string stsqlcon = "Data Source=127.0.0.1;Initial Catalog=ErrorMechanismDB;User ID=sa;pwd=95688859";
        static SqlConnection sqlcon = null;

        #region 访问数据库- 服务方法

        /// <summary>
        /// 访问数据库-- 双向语句 (执行 Select 查询操作)
        /// </summary>
        /// <param name="strsqlTow"></param>
        /// <returns></returns>
        public static DataSet GetDateSet(string strsqlTow)
        {

            Open(); //连接串
            //利用数据适配器将数据从数据库填充到DataSet中
            SqlDataAdapter sda = new SqlDataAdapter(strsqlTow, sqlcon);
           /// sda.SelectCommand.CommandTimeout = 3600;
            DataSet ds = new DataSet();
           //开始填充数据到ds中的表temp中
           sda.Fill(ds, "temp");
            Close();
            return ds;
        }
        public static DataTable GetDateTable(string strsqlTow)
        {
            Open(); //连接串
            DataTable DT = new DataTable();
            SqlDataAdapter myCommand = new SqlDataAdapter(strsqlTow, sqlcon);

            DataSet ds = new DataSet();
            myCommand.Fill(ds);

            DT = ds.Tables[0];
            myCommand.Dispose();
            ds.Dispose();
            sqlcon.Close();
            Close();


            return DT;
        }

        /// <summary>
        /// 访问数据库-- 单项语句方法(执行 Insert  、 Update 、Delete 语句)
        /// </summary>
        /// <param name="strsql">SQL拼接语句</param>
        /// <returns>如果执行成功 返回-1</returns>
        public static int ExecuteNonQuery(string strsql)
        {
            Open();//连接串
            SqlCommand cb = new SqlCommand(strsql, sqlcon); //执行SQL语句
            int i = cb.ExecuteNonQuery(); //执行语句并返回影响的行数
            Close();
            return i;
        }
        /// <summary>
        /// 打开数据库
        /// </summary>
        /// <returns></returns>
        private static void Open()
        {
            if (sqlcon == null)
            {
                sqlcon = new SqlConnection(stsqlcon); //如果链接对象是null 就先实例化一下对象
                sqlcon.Open(); //打开数据库
            }
            else
            {
                if (sqlcon.State == ConnectionState.Broken || sqlcon.State == ConnectionState.Closed) //如果数据库连接后 处于中断状态 那么需要先断开数据库 再重新连接
                {
                    sqlcon.Close();//先关闭数据库
                    sqlcon.Open(); //再打开数据库
                }

            }
        }
        /// <summary>
        /// 关闭数据库方法(只需调用一下 既可 关闭数据库)
        /// </summary>
        private static void Close()
        {
            if (sqlcon != null)


            {
                //如果数据库连接状态处于 链接中断 或者是 打开状态 我们都进行强制关闭数据库连接
                if (sqlcon.State == ConnectionState.Broken || sqlcon.State == ConnectionState.Open)
                {
                    sqlcon.Close();//关闭数据库
                }
            }
        }
        /// <summary>
        /// 查询所有的患者信息
        /// </summary>
        private void GetAllData()
        {
            //查询数据

        }
        #endregion
        #region 执行存储过程方法

        /// <summary>
        /// 执行存储过程的单线方法,返回影响的行数
        /// </summary>
        /// <param name="storedProcName">存储过程名</param>
        /// <param name="parameters">存储过程参数</param>
        /// <returns>影响的行数</returns>
        public static int RunIntProcedure(string storedProcName, IDataParameter[] parameters)
        {
            int result = 0;
            //SqlConnection connection = new SqlConnection(strsqlcon);
            try
            {
                 Open();
                SqlCommand command = BuildIntCommand(sqlcon, storedProcName, parameters);
                result = command.ExecuteNonQuery();//返回执行影响行数
                command.CommandType = CommandType.StoredProcedure;
                //result = (int)command.Parameters["ReturnValue"].Value;//返回存储过程的返回值
            }
            finally
            {
                Close();
            }


            return result;
        }


        /// <summary>
        /// 执行存储过程的双向方法
        /// </summary>
        /// <param name="storedProcName">存储过程名</param>
        /// <param name="parameters">存储过程参数</param>
        /// <param name="tableName">DataSet结果中的表名</param>
        /// <returns>DataSet</returns>
        public static DataSet RunDatsetProcedure(string storedProcName, IDataParameter[] parameters)
        {
            DataSet dataSet = new DataSet();
            Open();
            SqlDataAdapter sqlDA = new SqlDataAdapter();
            sqlDA.SelectCommand = BuildQueryCommand(sqlcon, storedProcName, parameters);
            sqlDA.Fill(dataSet, "temp");
            Close();
            return dataSet;
        }
        #endregion
        #region 存储过程服务方法

        /// <summary>
        /// 创建 SqlCommand 对象实例(用来返回一个整数值)
        /// </summary>
        /// <param name="storedProcName">存储过程名</param>
        /// <param name="parameters">存储过程参数</param>
        /// <returns>SqlCommand 对象实例</returns>
        private static SqlCommand BuildIntCommand(SqlConnection connection, string storedProcName, IDataParameter[] parameters)
        {
            SqlCommand command = BuildQueryCommand(connection, storedProcName, parameters);
            command.Parameters.Add(new SqlParameter("ReturnValue",
                SqlDbType.Int, 4, ParameterDirection.ReturnValue,
                false, 0, 0, string.Empty, DataRowVersion.Default, null));
            return command;
        }



        /// <summary>
        /// 构建 SqlCommand 对象(用来返回一个结果集,而不是一个整数值)
        /// </summary>


        /// <param name="connection">数据库连接</param>
        /// <param name="storedProcName">存储过程名</param>
        /// <param name="parameters">存储过程参数</param>
        /// <returns>SqlCommand</returns>
        private static SqlCommand BuildQueryCommand(SqlConnection connection, string storedProcName, IDataParameter[] parameters)
        {
            SqlCommand command = new SqlCommand(storedProcName, connection);
            command.CommandType = CommandType.StoredProcedure;
            foreach (SqlParameter parameter in parameters)
            {
                command.Parameters.Add(parameter);
            }
            return command;
        }

        #endregion
        
        
       
    }
}




以下是SQL 代码
create table Vipinfo ---用户信息表
(
Uid int identity(1,1),
U_Vidvarchar (30)unique,
患者IDvarchar(14),
姓名varchar(10) not null,
性别varchar(6) not null,
出生日期 datetime not null,
身份证varchar(38), 
会员卡号 varchar(30),
建档时间datetime  default(getdate()) not null
CONSTRAINT [PK_U_Vid] PRIMARY KEY  CLUSTERED (U_Vid,患者ID)ON [PRIMARY] 
)

go
create table Vipexpense 
(
Vidvarchar(30),
单据号varchar(30) not null,
消费类别varchar(10) not null,
金额decimal(18,2) not null,
积分decimal(18,2) not null,
经办人varchar(30) not null,
建档时间datetime  default(getdate()) not null,
)
--创建外键约束
BEGIN TRANSACTION
alter table dbo.Vipexpense add constraint FK_Vipexpense_Vipinfo
foreign key (Vid)
references dbo.Vipinfo([U_Vid]) ON UPDATE CASCADE ON DELETE CASCADE


go
Create table Goodsinfo
(
Gid int primary key identity(00001,00001), 
商品名称varchar(80) not null,
商品类型varchar(60) not null,
兑换积分decimal(18,2) not null,
供应商varchar(100) not null,
建档时间datetime  default(getdate()) not null,
)
go
create table Pointsfor
(
Pid int  primary key identity(001,001),
U_Vidvarchar(30) foreign key references Vipinfo(U_Vid), 
上次积分decimal(18,2)  not null,
Gid int foreign key references Goodsinfo(Gid), 
数量 int  not null,
所需积分decimal(18,2) not null,
兑换时间datetime default(getdate()) not null


)


现在的问题是为什么数据库会锁住?
[解决办法]
原因查出来了,是因为外键的约束引起,很奇怪,如果表中必须要有外键的约束请问该如何处理。
[解决办法]
string cardNum = ReaderCard.td;//获取卡号
            int cnum=cardNum.IndexOf("\0",0);//截取字符串
            string strsql1 = "select * from  dbo.Vipinfo where U_Vid='" + cardNum.Substring(0,cnum) + "'";//再次截取
            DataTable dt1= DBHelpSQL.GetDateTable(strsql1);
            if (dt1.Rows.Count >= 1)
            {
                MessageBox.Show("此张会员卡信息已存在!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Stop);
            }
          else
            {
               
                string card = this.Txtbcardnum.Text = ReaderCard.td;
                string strsql = "select 姓名,性别,出生日期,身份证号,患者id from B患者基本信息 where 患者id='" + card + "'";
                DataTable dt = DBHelpSQL.GetDateTable(strsql);
                TxtUname.Text = dt.Rows[0]["姓名"].ToString();//获取姓名
                Cmbsex.Text = dt.Rows[0]["性别"].ToString();//获取患者性别
                TxtbAge.Text = dt.Rows[0]["出生日期"].ToString();///获取患者年龄
                Txtsfz.Text = dt.Rows[0]["身份证号"].ToString();///获取身份证号

                /*使用Dataset 取值
                   // DataSet ds =DBHelpSQL.GetDateSet(strsql);
                 //// DataSet ds = new DataSet();
                 // foreach (DataRow col in ds.Tables[0].Rows)           //set.Tables[0].Rows 找到指定表的所有行 0这里可以填表名
                 //  {
                 //      Console.WriteLine(col[0].ToString());                 //col[0]这一行的索引是0单元格,也就是列,你只要在0这里填上你要输出的第几列就行了
                 //  }


        
    
         
                   //MessageBox.Show("读卡功能正在完善,敬请期待!", "读卡提示", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);//读卡提示信息
        
                 */
            }


[解决办法]
引用:
原因查出来了,是因为外键的约束引起,很奇怪,如果表中必须要有外键的约束请问该如何处理。

谁告诉你表中必须要有外键的约束, 你老师? 还是你经理?

这个用程序控制就好了, 多余的约束会影响数据库性能
[解决办法]
完整的程序应该包括客户端数据校验,
和数据库操作后异常处理。

热点排行