J2EE 事宜总结
J2EE 事务总结数据库事务数据库的事务级别:1)读取未提交(read uncommitted)最低的事务隔离级别,读事务不会
J2EE 事务总结
数据库事务
数据库的事务级别:
1)读取未提交(read uncommitted)
最低的事务隔离级别,读事务不会堵塞读事务,写事务不会堵塞读事务,但是会堵塞写事务。会造成脏读。
2)读取已提交(read committed)
写事务会堵塞写事务和读事务,但是读事务不会堵塞写事务和读事务。因为写事务堵塞读事务,所以不会造
成脏读。但是因为读事务不会堵塞写事务,如果读取事务时,有写事务在进行,会造成前后读取数据不一致,
就是所谓的 不可重复读。
3)可重复读(repeatable read)
写事务会堵塞写事务和读事务,读事务会堵塞写事务,但是读事务不会堵塞读事务。不会造成 不可重复读。
但是会造成幻读。(事务A读取与搜索条件相匹配的若干行。事务B以插入或删除行等方式来修改事务A的结果集,然后再提交。如果事务A重复该读取操作,则将获得不同的行集。采用这种方式所添加的行叫做幻影行 )
4)序列化(serializale)
最严格的事务级别。不会造成脏读、不可重复读、幻读。但是会极大的影响系统性能,因此应该避免设置成序列化,而
应该采用较低的隔离级别,然后采用并发控制策略来进行事务的并发访问控制。
JTA事务
Spring事务
http://vae.iteye.com/blog/476457
事务并发访问策略
1)同一系统事务
?
a.乐观锁
???? 认为系统中的事务并发更新不会很频繁。每次提交一个事务更新,如果发现数据被其他事务修改过,则修改失败。
实现方法:
Ⅰ.版本(version)字段:
在实体中增加一个版本控制字段,每次事务更新后就将版本字段的值加1。
example:
???? JDBC中实现:
????Select a.version....from Account as a where (where condition..) Update Account set version = version+1.....(another field) where version =?...(another contidition)
?? 如果update的更新结果的行数为0,说明实体从加载以来已经被其他事务修改过,会抛出自定义的乐观锁
? 异常。
?....... int rowsUpdated = statement.executeUpdate(sql); If(rowsUpdated= =0){ throws new OptimisticLockingFailureException(); } ........
?? hibernate 实现悲观锁:
??在实体类中加一个version字段
public class Account{ Long id ; ....... @Version //也可以采用XML文件进行配置 Int version ....... }
?Ⅱ.时间戳(timestamps):
每次要提交更新时将系统当前时间和实体加载时间进行比较,如果不一致,就会报告乐观锁失败,
从而回滚或重新尝试提价。缺点就是,当并发事务时间间隔小于当前系统平台的最小时间单位时,
会发生覆盖前一个事务结果的问题。
基于所有属性进行检测:
比较每个字段在读取后有没有被修改过。
b.悲观锁
认为系统中的并发更新会很频繁,并且事务失败了重来的开销很大。每次一个事务读取某一条记录,
就会把这条记录锁住,这样其他事务要想更新,必须等以前的事务提交或者回滚解除锁。可以控制
不可重复读的问题,但是无法避免幻读。
?example:
JDBC中使用悲观锁:
Select * from Account where ...(where condition).. for update.
?Hibernate实现悲观锁:
? ....... session.lock(account, LockMode.UPGRADE); ......
?或者可以采用如下方法加载对象:
session.get(Account.class,identity,LockMode.UPGRADE).
?
2)跨系统事务
1 楼 mingyang2013 2011-09-15 "写事务会堵塞写事务和读事务":请问一下,一个事务通常包含一些列操作,可能是读,可能是写,也可能是读和写,怎么规定或判定这个事务是“读”事务还是“写”事务呢?