在同一事务条件下,回滚和不提交,表现是一样的
但是还有些差别
事务处理,是将 *** 作事件交给数据库(模拟)运行,直到commit *** 作,才使得修改实际产生效果,你可以看做是未提交事务都是处于一个临时库中进行
回滚是对于同一个事务,如果产生了错误,那么取消这个临时库中的 *** 作,不对实际数据产生影响
最主要的区别在于,如果不回滚,这些临时 *** 作会持续到这个个connection结束为止,也就是虽然你看不到,但是临时库的 *** 作依然存在,而回滚是即时生效,其实都是回滚了,只是时间点的不一样
2.
我说你在开玩笑吧。没有提交事务并不代表你对数据库的改变不存在,如果是脏读的隔离层级你修改数据到提交完成前的变更其他访问者也是可以看到的。只有你提交后这部分修改才确认不会变更而已,哪怕设定了其他隔离级别也可以看到了。
如果你不回滚,那么线程就停在哪里搁着?制造出数据库死链放着不管直到数据库认为这个连接超时自动断开并自动回滚?
ISOLATION_READ_UNCOMMITTED:允许读取其他并发事务还未提交的更新,会导致事务之间的3个缺陷发生,这是速度最快的一个隔离级别,但同 时它的隔离级别也是最低
查看 MySQL 客户端的事务提交方式命令:select @@autocommit修改 MySQL 客户端的事务提交方式为手动提交命令:set @@autocommit = 0
(注:0 表示手动提交,即使用 MySQL 客户端执行 SQL 命令后必须使用commit命令执行事务,否则所执行的 SQL 命令无效,如果想撤销事务则使用 rollback 命令。1 表示自动提交,即在 MySQL 客户端不在需要手动执行 commit 命令。)
MySQL 在自动提交模式下,每个 SQL 语句都是一个独立的事务。
注意:
1、手动设置set @@autocommit = 0,即设定为非自动提交模式,只对当前的mysql命令行窗口有效,打开一个新的窗口后,默认还是自动提交;
2、对于非自动提交模式,比如在命令行中添加一条记录,退出命令行后在重新打开命令行,之前插入的记录是不在的。(用select * from + 表名 验证一下就可以了)
参考:
https://www.cnblogs.com/digdeep/p/4892953.html
https://blog.csdn.net/u013235478/article/details/68062939/
从 information_schema.innodb_trx 表中查看当前未提交的事务
lock_wait_timeout 表示获取metadata lock的超时(单位为秒),允许的值范围为1到31536000(1年)。 默认值为31536000。详见 https://dev.mysql.com/doc/refman/5.6/en/server-system-variables.html#sysvar_lock_wait_timeout 。默认值为一年!!!已哭瞎!将其调整为30分钟
1.2 查看表是否太大
看出表非常小,不存在由于数据量大导致更新慢的问题;
1.3 查看引擎状态
数据量太大,一屏幕都显示不完,不看了。
既然几个比较直接的方法都查不到原因,那只能更深入的查下了,我打算从数据字典中查下(information_schema,performance_schema):
1.4,查找当前等待事务:
显示空。
查找 information_schema 中的 事件表(EVENTS )、锁等待表(INNODB_LOCK_WAITS),innodb 当前出现的锁****(INNODB_LOCKS )均没看到异常(这里就不贴图了)。
1.5 查找事务
既然造成该锁的原因是事务没有提交导致的,那我们应该去查找当前是否有事务在运行( runing 注:由于事务一直是runing状态,这也就是为什么我之前查找各种锁都找不到的原因)
不过有重大发现:一个 trx_mysql_thread_id: 275255348 是从 trx_started: 2015-12-03 14:58:45 一直处于runing状态的。
既然我们找到了id了 那我们再回顾使用 show processlist 查找该ID就行了:
发现了吗,该ID一直是sleep状态。很难发现该进程打开了这个表(可以通过show open tables 查看当前打开的表)。
解决办法: 询问了开发这个点的脚本, *** 作。确认后通过后台mysql 直接kill掉这个进程,业务的alter *** 作瞬间完成。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)