全局变量 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 肯定有问题的,会出现很多异常
|