调试代码深度理解数据库事务

定义如下

查询: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操作事务中不能调用其他事务对当前表进行操作,否则会造成死锁
四、同一个事务必须共用一个连接,且在执行过程中不能关闭
五、不在同一个事务中不能共用同一个连接

原文地址:https://www.cnblogs.com/zhyj/p/2734292.html