精华帖 (0) :: 良好帖 (5) :: 新手帖 (0) :: 隐藏帖 (12)
|
|
---|---|
作者 | 正文 |
发表时间:2011-08-03
最后修改:2011-08-03
查阅网上的一些资料和自己实践体会后,弄了如下心得。不知是否恰当正确,发出来大家点评一下: 在Spring中定义了5中不同的事务隔离级别。 1. ISOLATION_DEFAULT(一般情况下使用这种配置既可) 这是一个PlatfromTransactionManager默认的隔离级别,使用数据库默认的事务隔离级别。 2. ISOLATION_READ_UNCOMMITTED 这是事务最低的隔离级别,它充许别外一个事务可以看到这个事务未提交的数据。这种隔离级别会产生脏读,不可重复读和幻像读。 (大部分数据库缺省的事物隔离级别都不会出现这种状况) 3. ISOLATION_READ_COMMITTED 保证一个事务修改的数据提交后才能被另外一个事务读取。另外一个事务不能读取该事务未提交的数据。这种事务隔离级别可以避免脏读出现,但是可能会出现不可重复读和幻像读。 什么是脏读? 例如: 张三的工资为5000,事务A中把他的工资改为8000,但事务A尚未提交。 与此同时, 事务B正在读取张三的工资,读取到张三的工资为8000。 随后, 事务A发生异常,而回滚了事务。张三的工资又回滚为5000。 最后, 事务B读取到的张三工资为8000的数据即为脏数据,事务B做了一次脏读。 (大部分数据库缺省的事物隔离级别都不会出现这种状况) 4. ISOLATION_REPEATABLE_READ 这种事务隔离级别可以防止脏读,不可重复读。但是可能出现幻像读。 什么是不可重复读? 例如: 在事务A中,读取到张三的工资为5000,操作没有完成,事务还没提交。 与此同时, 事务B把张三的工资改为8000,并提交了事务。 随后, 在事务A中,再次读取张三的工资,此时工资变为8000。在一个事务中前后两次读取的结果并不致,导致了不可重复读。 (大部分数据库缺省的事物隔离级别都不会出现这种状况) 5. ISOLATION_SERIALIZABLE 这是花费最高代价但是最可靠的事务隔离级别。事务被处理为顺序执行。除了防止脏读,不可重复读外,还避免了幻读。 什么是幻读? 例如: 目前工资为5000的员工有10人,事务A读取所有工资为5000的人数为10人。 此时, 事务B插入一条工资也为5000的记录。 这是,事务A再次读取工资为5000的员工,记录为11人。此时产生了幻读。 (大部分数据库缺省的事物隔离级别都会出现这种状况,此种事物隔离级别将带来表级锁) 说明 :Oracle数据库缺省的事物隔离级别已经保证了避免脏读和不可重复读。但可能会幻读,避免幻读需要加表级锁,Oracle缺省行级锁。在基于Spring的事物配置中一定要慎重使用ISOLATION_SERIALIZABLE的事物隔离级别。这种配置会使用表级锁,对性能影响巨大。一般没有特殊需要的话,配置为使用数据库缺省的事物隔离级别便可。
如下为开源产品分享:
G4Studio是一套面向中小软件企业及个人开发者的集设计、开发、部署、后期维护于一体,力求覆盖整个软件生命周期的高品质开源产品套件。
源码下载及在线演示: http://www.g4studio.org/thread-12-1-1.html 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2011-08-03
顶一顶~~~哈哈~~~
|
|
返回顶楼 | |
发表时间:2011-08-03
spring 事物看哈
|
|
返回顶楼 | |
发表时间:2011-08-04
什么是不可重复读?
例如: 在事务A中,读取到张三的工资为5000,操作没有完成,事务还没提交。 与此同时, 事务B把张三的工资改为8000,并提交了事务。 随后, 在事务A中,再次读取张三的工资,此时工资变为8000。在一个事务中前后两次读取的结果并不致,导致了不可重复读。 (大部分数据库缺省的事物隔离级别都不会出现这种状况) ----------------------------------------------- 这儿有错,大部分数据库比如oracle默认是read committed,所以是会出现不可重复读的。 |
|
返回顶楼 | |
发表时间:2011-08-04
eredlab 写道
什么是脏读? 例如: 张三的工资为5000,事务A中把他的工资改为8000,但事务A尚未提交。 与此同时, 事务B正在读取张三的工资,读取到张三的工资为8000。 随后, 事务A发生异常,而回滚了事务。张三的工资又回滚为5000。 最后, 事务B读取到的张三工资为8000的数据即为脏数据,事务B做了一次脏读。 (大部分数据库缺省的事物隔离级别都不会出现这种状况) 脏读的举例有问题吧。 事务A未提交,数据库中的数据不会发生改变。事务B读取到的工资怎么会是8000呢? 应该是5000啊。
应该是: 事务A要将A的工资改为8000. 但事务A尚未提交 事务B此时查询A的工资。查得结果为5000. 随后事务A提交。此时事务B读到的5000则为脏数据。 |
|
返回顶楼 | |
发表时间:2011-08-04
事务没提交,你的8000怎么写到数据库里的。这个帖子的是实际意义不大
|
|
返回顶楼 | |
发表时间:2011-08-04
eredlab 写道
什么是脏读? 例如: 张三的工资为5000,事务A中把他的工资改为8000,但事务A尚未提交。 与此同时, 事务B正在读取张三的工资,读取到张三的工资为8000。 随后, 事务A发生异常,而回滚了事务。张三的工资又回滚为5000。 最后, 事务B读取到的张三工资为8000的数据即为脏数据,事务B做了一次脏读。 (大部分数据库缺省的事物隔离级别都不会出现这种状况) 这个没错。大部分数据库默认事务隔离级别是ReadCommitted,不会出现脏读。
hengheng 写道
脏读的举例有问题吧。
事务A未提交,数据库中的数据不会发生改变。事务B读取到的工资怎么会是8000呢? 应该是5000啊。
应该是: 事务A要将A的工资改为8000. 但事务A尚未提交 事务B此时查询A的工资。查得结果为5000. 随后事务A提交。此时事务B读到的5000则为脏数据。
你举的例子是不对。
1、事务A要将A的工资改为8000. 但事务A尚未提交;
2、事务B此时查询A的工资。 这时候的结果取决于事务B的隔离级别。 假如事务B的隔离级别是ReadUncommitted,这时候事务B读到8000,也就是发生脏读。 假如事务B的隔离级别是ReadCommitted,这时候事务B会发生阻塞,直到事务A提交或回滚,才能返回。不会发生脏读。
|
|
返回顶楼 | |
发表时间:2011-08-04
bitray 写道 事务没提交,你的8000怎么写到数据库里的。这个帖子的是实际意义不大
难道事务没提交,数据就不会写到数据库? 当然会写到数据库,要不然DBMS要数据库锁、回滚机制干嘛? 是hibernate用多了的后遗症吧。 ReadUncommitted隔离级别的作用就是来读取 已经写到数据库、但尚未提交或者回滚的数据的! |
|
返回顶楼 | |
发表时间:2011-08-04
hengheng 写道
eredlab 写道
什么是脏读? 例如: 张三的工资为5000,事务A中把他的工资改为8000,但事务A尚未提交。 与此同时, 事务B正在读取张三的工资,读取到张三的工资为8000。 随后, 事务A发生异常,而回滚了事务。张三的工资又回滚为5000。 最后, 事务B读取到的张三工资为8000的数据即为脏数据,事务B做了一次脏读。 (大部分数据库缺省的事物隔离级别都不会出现这种状况) 脏读的举例有问题吧。 事务A未提交,数据库中的数据不会发生改变。事务B读取到的工资怎么会是8000呢? 应该是5000啊。
应该是: 事务A要将A的工资改为8000. 但事务A尚未提交 事务B此时查询A的工资。查得结果为5000. 随后事务A提交。此时事务B读到的5000则为脏数据。 这就叫脏读。脏读就是可以读到未提交的事务。这只是定义,事实上几乎没有数据库在这种模式下工作。 |
|
返回顶楼 | |
发表时间:2011-08-04
ironsabre 写道 什么是不可重复读?
例如: 在事务A中,读取到张三的工资为5000,操作没有完成,事务还没提交。 与此同时, 事务B把张三的工资改为8000,并提交了事务。 随后, 在事务A中,再次读取张三的工资,此时工资变为8000。在一个事务中前后两次读取的结果并不致,导致了不可重复读。 (大部分数据库缺省的事物隔离级别都不会出现这种状况) ----------------------------------------------- 这儿有错,大部分数据库比如oracle默认是read committed,所以是会出现不可重复读的。 ironsabre是对的。 |
|
返回顶楼 | |