定义如下
查询:Q表示 ,其他操作(insert、update、delete):IUD表示
一直以来对数据库事务理解总是停留在概念上,项目中应用事务总是感觉不踏实,是懂非懂的感觉。最近做的项目中遇到了问题不得不深度剖析,调试,我的需求如下:
从A开始执行带事务操作,执行完毕后提交,好像一切都顺理成章,但是只要执行就会假死,过好长时间提示超时。后来我发现IDU()操作共用同一个数据库连接且在同一个事务内,而Q()使用了不同的数据库连接,不在同一个事务内,以至于造成上述问题,随后我会给出解决方案,先总结.Net数据库事务中的几个结论:
一、Q操作不会锁住表,IUD操作会锁住表
实验:
1.一个Q事务中调用其他Q操作
OleDbConnection con = new OleDbConnection();
con.ConnectionString = System.Configuration.ConfigurationManager.AppSettings["conStr"];
con.Open();
OleDbConnection con1 = new OleDbConnection();
con1.ConnectionString = System.Configuration.ConfigurationManager.AppSettings["conStr"];
con1.Open();
string sql1 = @"select count(1) from ATTACH_PROPERTY where PK_GUID ='1'";
OleDbCommand myCom = new OleDbCommand();
myCom.Connection = con;
myCom.Transaction =con.BeginTransaction();
OleDbCommand myCom1 = new OleDbCommand();
myCom1.Connection = con1;
myCom.CommandText = sql1;
object flag=myCom.ExecuteScalar();
myCom1.CommandText = sql1;
object flag1=myCom1.ExecuteScalar();
myTran.Commit();
con开启了事务,在con事务提交之前我们又调用了con1连接对同一个表进行查询,结果正确
2.一个Q事务在提交之前使用查询分析器查询
OleDbConnection con = new OleDbConnection();
con.ConnectionString = System.Configuration.ConfigurationManager.AppSettings["conStr"];
con.Open();
string sql1 = @"select count(1) from ATTACH_PROPERTY where PK_GUID ='1'";
OleDbCommand myCom = new OleDbCommand();
myCom.Connection = con;
myCom.Transaction =con.BeginTransaction();
myCom.CommandText = sql1;
object flag=myCom.ExecuteScalar();
myTran.Commit();
在最后myTran.Commit()处设置断点,然后用数据库的查询分析器执行sql1语句,结果正确。
3.一个IDU事务中调用其他Q操作
OleDbConnection con = new OleDbConnection();
con.ConnectionString = System.Configuration.ConfigurationManager.AppSettings["conStr"];
con.Open();
string sql= @"insert into ATTACH_PROPERTY(PK_GUID,Property1,Property2,Property3,Property4,Remark) values ('1','2','2','2','2','3') ";
string sql1 = @"select count(1) from ATTACH_PROPERTY where PK_GUID ='1'";
OleDbCommand myCom = new OleDbCommand();
myCom.Connection = con;
myCom.Transaction =con.BeginTransaction();
myCom.CommandText = sql;
myCom.ExecuteNonQuery();
myCom1.CommandText = sql1;
object flag=myCom1.ExecuteScalar();
myTran.Commit();
con是一个IDU操作切开启了事务,con1没有应用事务,当执行到object flag=myCom1.ExecuteScalar();的时候,一直等待,只到超时。
4.一个IDU事务提交之前使用查询分析器查询
OleDbConnection con = new OleDbConnection();
con.ConnectionString = System.Configuration.ConfigurationManager.AppSettings["conStr"];
con.Open();
string sql= @"insert into ATTACH_PROPERTY(PK_GUID,Property1,Property2,Property3,Property4,Remark) values ('1','2','2','2','2','3') ";
OleDbCommand myCom = new OleDbCommand();
myCom.Connection = con;
myCom.Transaction =con.BeginTransaction();
myCom.CommandText = sql;
myCom.ExecuteNonQuery();
myTran.Commit();
二、IUD操作事务时不在同一个事务中对该表的操作将被挂起,同一事务则不会
三、IUD操作事务中不能调用其他事务对当前表进行操作,否则会造成死锁
四、同一个事务必须共用一个连接,且在执行过程中不能关闭
五、不在同一个事务中不能共用同一个连接