大家好,又见面了,我是你们的朋友全栈君。
1 .概述
很多人会有这样的疑问,mysql读写分离后,我的事务怎么处理呢。
不是说mysql不支持跨库事务吗?
那我引入mycat这个中间件后事务是否是安全的呢,它是怎么运作的呢。
今天我们就来实验一下
2. 设置
首先设置事务锁的过期时间是5
innodb_lock_wait_timeout = 5
意思是前面有人已经锁定这一行准备更新了,而你现在又去更新这行,那你只能等,等5秒。前面的人还没进行事务提交,那你当前的进程就会报错
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
所以必须回滚。
3.主从库 各自开启事务实验,检验事务锁
来验证一下主库和从库 分别对同一行数据操作时 ,事务是否安全
主:
mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from tb_books where id =2 for update;
+——+——-+———–+————+—-+
| name | price | bookCount | author | id |
+——+——-+———–+————+—-+
| 123 | 88 | 100 | beiduofen3 | 2 |
+——+——-+———–+————+—-+
1 row in set (0.08 sec)
表tb_books的id的主键,这里执行了行锁 ,然后去看看从服务器
从:
mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)
mysql> update tb_books set price=77 where id =2;
Query OK, 1 row affected (0.16 sec)
Rows matched: 1 Changed: 1 Warnings: 0
可以看到即使主服务器已经 把id=2 这行数据已经锁定, 但是从服务器还是可以更新到id为2的这条记录
由此可见,简单的读写分离 事务并不同步 。MySQL不支持跨库事务
那么我们只能借助mycat来实现弱跨库事务了
4 . 通过mycat 分别开始事务后,检验事务锁
配置: 已经用mycat 配置好主从读写分离
我们登陆mycat ,新开2个窗口进程,分别叫mycat1 和 mycat2
===mycat1 进程===
mysql> start transaction;
Query OK, 0 rows affected (0.08 sec)
mysql> select * from tb_books where id=1 for update;
+——+——-+———–+————+—-+
| name | price | bookCount | author | id |
+——+——-+———–+————+—-+
| 123 | 33 | 100 | beiduofen2 | 1 |
+——+——-+———–+————+—-+
1 row in set (0.04 sec)
mysql> update tb_books set price=9 where id =1;
Query OK, 1 row affected (0.17 sec)
Rows matched: 1 Changed: 1 Warnings: 0
这里我们没有操作提交或回滚。
然后我们继续转到mycat2进程操作
===mycat2 进程===
我们在这进行同样的操作
mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)
mysql> update tb_books set price=10 where id =1;
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
可以看到 mycat2进程 已经不能对id为1的记录进行操作 ,触发了行锁
而且在主数据库和从数据库的日志里 也没有发现此条sql日志。
由此看来应该是在mycat的层面上处理了。
并且如果该进程如果发生过事务 , 接下来的无论是select或update的操作都会发生在写主机上(不知道是不是我的设置问题), 无论执行多少次读的请求, 从主机都不会收到select的任务。(我的mycat策略是主数据库只负责写操作,从服务器只负责读操作)
要新进来的进程或这个进程已经断开,才会按读写分离规则分配。
5.日志和总结
这里记录下mycat触发行锁时 的日志
2020-02-03 04:55:04.437 DEBUG [$_NIOREACTOR-0-RW] (io.mycat.backend.datasource.PhysicalDatasource.releaseChannel(PhysicalDatasource.java:442)) – release channel MySQLConnection [id=12, lastTime=1580734504421, user=slaveuser, schema=testtest, old shema=testtest, borrowed=true, fromSlaveDB=true, threadId=62, charset=utf8, txIsolation=3, autocommit=true, attachment=null, respHandler=null, host=192.168.133.135, port=3306, statusSync=null, writeQueue=0, modifiedSQLExecuted=false]
2020-02-03 04:55:04.437 DEBUG [$_NIOREACTOR-0-RW] (io.mycat.backend.datasource.PhysicalDatasource.releaseChannel(PhysicalDatasource.java:442)) – release channel MySQLConnection [id=6, lastTime=1580734504421, user=root, schema=testtest, old shema=testtest, borrowed=true, fromSlaveDB=false, threadId=28, charset=utf8, txIsolation=3, autocommit=true, attachment=null, respHandler=null, host=localhost, port=3306, statusSync=null, writeQueue=0, modifiedSQLExecuted=false]
额外的一点知识
select * from information_schema.innodb_trx\G;
通过这个语句可以看到系统里的锁
总结一下。
单单读写分离配置后 事务安全需要借助mycat
6.参考
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/134264.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...