锁定老帖子 主题:只读查询是否需要启动事务管理,兼论只读事务
该帖已经被评为精华帖
|
|
---|---|
作者 | 正文 |
发表时间:2005-01-06
mysql默认是repeatable read
oracle默认是read commited 两者的isolation level不一样,两者在未加锁的情况下的表现都是正确的。 |
|
返回顶楼 | |
发表时间:2007-06-10
cocoa 写道 mysql默认是repeatable read
oracle默认是read commited 两者的isolation level不一样,两者在未加锁的情况下的表现都是正确的。 路过正好看到,cocoa说的没错,这个问题当时学习mysql事务隔离机制的时候碰到过,当时也查了些资料,所以想补充几点: mysql的默认的事务隔离级别是repeatable read,它是使用快照机制实现的。举个例子:开两个mysql的客户端:console_A,console_B。将autocommit设为false,假设有表t_user(id,name),中有一条记录 [1,'evan']。 接着按顺序执行: 1.start transaction; 2.console_A先执行了一条select语句:select * from t_user,它看到的是[1,'evan'];(注意,这个时候mysql会为该表生成一个快照) 3.console_B执行一条update语句:update t_user set name='evanz_chg' where id = 1;并且用commit提交; 4.console_A再次执行:select * from t_user,它看到的仍然是[1,'evan'](是快照中的)。 5.console_A提交commit(会释放快照),然后执行select * from t_user,终于可以看到被console_B更新的记录了[1,'evan_chg']. 接着往下分析: 1、hibernate,默认情况下,autoCommit被设置为false,robbin的例子中由spring管理事务也就是说,commit由spring来完成的,如果把spring关于事务传播的属性注释掉,就等于没人会去做commit的动作,这样的话,这个session永远只是在快照中取数据。 2、至于换了c3p0就没问题了,我猜想可能是在conn.close()的时候,c3p0自动做了commit操作,而hibernate自己的连接池只是简单的把conn放回pool。 3、我把上面2和3的执行步骤换了一下,发现console_A取到的是[1,'evab_chg'],不是save-point前的[1,'evan'],看来mysql还没做到这一点 |
|
返回顶楼 | |