
全局变量 gMySQLClient=new MySQLClient(127.0.0.1:3306),gRedisClient =new RedisClient(127.0.0.1:6379);
场景 1-MySQL: 线程 A: resA=gMySQLClient.Exec("Select * From A WHERE id=1").GetExecResult(); 线程 B: resB=gMySQLClient.Exec("Select * From B WHERE id=1").GetExecResult(); 该场景有没可能发生 resA 是线程 B 返回的结果?假设线程 B 的结果比线程 A 先返回 场景 2-MySQL: 线程 A: resA1=gMySQLClient.Exec("BEGIN").GetExecResult(); resA2=gMySQLClient.Exec("Update A SET a='a1' WHERE id=1").GetExecResult(); sleep(5*Time.Second);//t1 时刻,resA2 执行成功,resA3 暂未执行 resA3=gMySQLClient.Exec("Update B SET b='b1' WHERE id=1").GetExecResult(); resA4=gMySQLClient.Exec("COMMIT").GetExecResult(); 线程 B: resB1=gMySQLClient.Exec("BEGIN").GetExecResult(); resB2=gMySQLClient.Exec("Update C SET c='c1' WHERE id=1").GetExecResult() resA3=gMySQLClient.Exec("COMMIT").GetExecResult(); 该场景有没可能发生线程 B 执行的 COMMIT 恰好在 t1 时刻执行,然后把线程 A 提前 COMMIT 生效了? 场景 3-Redis: 线程 A: resA=gRedisClient.Get("keyA") 线程 B: resB=gRedisClient.Get("keyB") 该场景有没可能发生 resA 是线程 B 返回的结果?假设线程 B 的结果比线程 A 先返回 不太清楚它们底层的处理方式,恳请大佬解答,谢谢~
1 NewDraw 2019-06-03 23:23:13 +08:00 via Android 这些都是同步阻塞调用,不会出现你说的问题,高并发情况下,你应该考虑的是性能是否满足需求。 |
2 billlee 2019-06-03 23:46:36 +08:00 场景二 mysql 事务是肯定不行的,两个事务会交织到一起 其它两个场景要看实现,一般你用的库会说明。 |
5 sagaxu 2019-06-04 00:06:26 +08:00 via Android 一般都不行,只有少数库可以 |
7 wisefree 2019-06-04 07:10:33 +08:00 每个线程用不同的 connection |
9 billlee 2019-06-05 23:34:45 +08:00 @coderqbc #4 显然是不行的。一般有两种方案 1. 使用连接池,每次要用的时候从连接池获取一个连接,只在同一个线程中使用,一般就是很紧凑的局部代码块中使用。用完释放。 2. 用 thread-local 语义,每个线程创建一个连接。许多 web 相关的框架会使用这种方案。 |
10 chenhongron 2019-06-13 14:58:01 +08:00 via Android 同一个 session 肯定有问题的,会出现很多异常 |