数据库事务
一、事务传播:
事务传播发生在类似以下情形:
class ServiceA { //事务1 void methodA(){ new ServiceB().methodB(); } } class ServiceB { //事务2 void methodB(){ } }
假设methodB的配置是:
1: PROPAGATION_REQUIRED
如果methodA在事务里,那么methodB也在这个事务中运行。
如果methodA不在事务里,那么methodB重新建立一个事务运行。
2: PROPAGATION_SUPPORTS
如果methodA在事务里,那么methodB也在这个事务中运行。
如果methodA不在是事务里,那么methodB在非事务中运行。
3: PROPAGATION_MANDATORY
如果methodA在一个事务里,那么methodB也在这个事务中运行。
如果methodA不在一个是事务里,那么methodB抛出异常。
4: PROPAGATION_REQUIRES_NEW
不管methodA在不在事务里,methodB都重新建立一个事务运行。
methodB事务运行时,methodA事务挂起;methodB事务结束后,methodA事务继续。
5: PROPAGATION_NOT_SUPPORTED
不管methodA在不在事务里,methodB都在非事务中运行。
methodB以非事务运行,methodA事务挂起;methodB运行完,methodA事务继续。
6: PROPAGATION_NEVER
如果methodA在一个事务里,那么methodB抛出异常。
7: PROPAGATION_NESTED
methodB的事务是methodA事务的内嵌事务。
methodB失败回滚到它执行前的 SavePoint,methodA加以处理methodB异常
1. 我们要设置 transactionManager 的 nestedTransactionAllowed 属性为 true。
2. java.sql.Savepoint 必须存在, 即 jdk 版本要 1.4+
3. Connection.getMetaData().supportsSavepoints() 必须为 true, 即 jdbc drive 必须支持 JDBC 3.0
参考:
http://www.blogjava.net/freeman1984/archive/2010/04/28/319595.html
http://www.iteye.com/topic/35907
二、事务隔离
1、Serializable:最严格的级别,事务串行执行,资源消耗最大;
2、REPEATABLE READ:保证了一个事务不会修改已经由另一个事务读取但未提交(回滚)的数据。避免了“脏读取”和“不可重复读取”的情况,但是带来了更多的性能损失。
3、READ COMMITTED:大多数主流数据库的默认事务等级,保证了一个事务不会读到另一个并行事务已修改但未提交的数据,避免了“脏读取”。该级别适用于大多数系统。
4、Read Uncommitted:保证了读取过程中不会读取到非法数据。隔离级别在于处理多事务的并发问题。
1: Dirty reads--脏读。
比如事务A的未提交(还依然缓存)的数据被事务B读走,如果事务A失败回滚,会导致事务B所读取的的数据是错误的。
2: non-repeatable reads--不可重复读。
比如事务A中两处读取数据-total-的值。在第一读的时候,total是100,然后事务B就把total的数据改成200,事务A再读一次,结果就发现,total竟然就变成200了,造成事务A数据混乱。
3: phantom reads--幻读。
数据集改变。比如Select account.id where account.name="ppgogo*",第一次读去了6个符合条件的id,第二次读取的时候,由于事务b把一个帐号的名字由"dd"改成"ppgogo1",结果取出来了7个数据。
脏读 | 不可重复读 | 幻读 | |
Serializable | 不会 | 不会 | 不会 |
Repeatable Read | 不会 | 不会 | 会 |
Read Committed | 不会 | 会 | 会 |
Read Uncommitted | 会 | 会 | 会 |
参考:
已有 0 人发表留言,猛击->> 这里<<-参与讨论
ITeye推荐