论坛首页 Java企业应用论坛

只读查询是否需要启动事务管理,兼论只读事务

浏览 30209 次
该帖已经被评为精华帖
作者 正文
   发表时间:2005-01-06  
mysql默认是repeatable read
oracle默认是read commited
两者的isolation level不一样,两者在未加锁的情况下的表现都是正确的。
1 请登录后投票
   发表时间: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还没做到这一点
1 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics