并行事务同时更新同一条记录

程序大概代码。mysql

sql语句sql

 

 

首先调试程序,等程序断下来以后,在浏览器从新发起一次请求,模拟双线程。这时调试窗口有线程(ps:这里用到的是mysql自带的链接池)浏览器

 事务开始但还没更新该记录时,该行还未被锁定,这是还能够更新dom

这时6号线程下一步就执行更新操做了ide

6号线程执行完以后,因为事务ID为14的记录被锁定,能够看到已经不能修改了,在排队等待事务关闭,若是等待太久直接取消此次操做性能

这时8号线程也在执行更新ID为14的操做,可是因为上一个事务未关闭,致使被锁,在排队等待。spa

能够看到mysql取消操做了。线程

已经异常了,并且链接已经关闭了3d

这时手动释放事务,因为是链接池,调用Close()并非真正关闭链接只是放回链接池。因此要释放事务,否则下次得到该链接时会出错。并且还会致使死锁。调试

最后,总结并行事务第一个事务会锁住更新的记录,下一个事务操做(更新或删除)该记录时排队等待上一个事务释放锁,若是等待过长会取消操做,而且抛出异常,捕获异常进行相应的操做回滚事务或关闭链接释放锁,否则会致使死锁。而且上一个事务提交以后,下一个事务的回滚不会影响到上一个事务的操做。

 1 string connString = "Server=localhost;Database=test;Uid=root;Pwd=root;Charset=utf8;pooling=true;Min Pool Size=2;Max Pool Size=20;";
 2             MySqlConnection con = new MySqlConnection(connString);
 3             con.Open();
 4             Random r = new Random();
 5             int n = r.Next(100);
 6            
 7             string sql = "update Nc_A set name='gfeng"+n.ToString()+"' where id=14";
 8             MySqlCommand com = new MySqlCommand(sql, con);
 9             MySqlTransaction tran = con.BeginTransaction();
10             try
11             {
12                 int rowcount = com.ExecuteNonQuery();
13                 int k = 0;
14                 int jk = 0;
15                 int jk2 = 0;
16                 if (HttpContext.Cache["n"] == null)
17                 {
18                     tran.Commit();
19                     HttpContext.Cache["n"] = n;
20                 }
21                 else
22                 {
23                     tran.Rollback();
24                 }
25 
26                 con.Close();
27             }
28             catch
29             {
30                 con.Close();
31             }
View Code

固然不是更新同一条记录是各不影响的。主要仍是要理解锁和事务的机制(之间是有区别的,用事务比用锁性能要低,毕竟要悬挂事务用于回滚或提交)。

相关文章
相关标签/搜索