在我们的应用中,有两个很重要的概念:事务的隔离级别和传播方式, 指的是:事务过程中对事务资源的锁定级别和事务过程的行为方式描述
先说事务隔离级别,可以看com.paic.pafa.app.lwc.service.transaction. TransactionDefinition
ISOLATION_READ_UNCOMMITTED
ISOLATION_READ_COMMITTED
ISOLATION_REPEATABLE_READ
ISOLATION_SERIALIZABLE
这几个级别的含义网上的资料很多,介绍含义的同时又引入一些概念:不可重复读、脏读、幻读等等,一些简单的概念被弄复杂了。我就以数据库资源来简单说一下这几个级别属性。
ISOLATION_READ_UNCOMMITTED:比如A事务新增了一条数据但没有commit,另外B事务能读取到这条数据,这表明事务资源完全没有锁机制,出现脏读;
ISOLATION_READ_COMMITTED:比如A事务做“查询一”得到10条记录,然后做其他事情,这期间另外B事务插入并提交了一条数据,A事务再做了一次同样的查询逻辑“查询二”,这个时候查出11条记录,这表明事务资源提供了类似于单行锁,避免了脏读,但不可重复读(查询一和查询二结果不一样)。
ISOLATION_REPEATABLE_READ:比如A事务做“查询一”得到10条记录,然后做其他事情,这期间另外B事务插入并提交了一条数据,A事务再做了一次同样的查询逻辑“查询二”,这个时候查出还是10条记录。但是如果B事务不是提交,而是删除了10条记录中的一条。A事务是看不到这个变化的,这表明事务资源提供了类似于查询结果集的多行锁,避免了不可重复读,但出现了幻读(一条记录已经不存在了,但在A事务中还继续可见,出现幻觉)
ISOLATION_SERIALIZABLE:最高级别,这表明事务资源提供了类似于表锁,脏度、不可重复读、幻读都不会出现。
再说传播方式,可以看com.paic.pafa.app.lwc.service.transaction.support. AbstractPlatformTransactionManager
传播方式实际上来源EJB规范。EJB规范定义了六种:NotSupported,Required,Supports,RequiresNew,Mandatory,Never。
PAFA相对应的定义了:PROPAGATION_NOT_SUPPORTED,PROPAGATION_REQUIRED,PROPAGATION_SUPPORTS,PROPAGATION_REQUIRES_NEW,PROPAGATION_MANDATORY,PROPAGATION_NEVER
这些都代表了什么意思呢?这些都是描述事务过程的行为。
1. PROPAGATION_REQUIRED 如果存在一个事务,则支持当前事务。如果没有事务则开启一个新的事务
methodA(){
dosomethingA();
methodB();
}
# PROPAGATION_REQUIRED // methodB的事务传播属性为PROPAGATION_REQUIRED
methodB(){
dosomethingB();
}
如果调用methodA时,如果没有处在事务中,当调用methodB时,事务管理器会打开一个新事务。如果methodA处于一个事务TsA中,在调用methodB时,methodB会自动加入到已有的事务TsA
2. PROPAGATION_SUPPORTS 如果存在一个事务,支持当前事务。如果没有事务,则非事务的执行
methodA(){
dosomethingA();
methodB();
}
# PROPAGATION_SUPPORTS // methodB的事务传播属性为PROPAGATION_SUPPORTS
methodB(){
dosomethingB();
}
如果调用methodA时,如果没有处在事务中,当调用methodB时,没有事务保护的运行。如果methodA处于一个事务TsA中,在调用methodB时,methodB会自动加入到已有的事务TsA
3. PROPAGATION_REQUIRES_NEW 总是开启一个新的事务。如果一个事务已经存在,则将这个存在的事务挂起
methodA(){
dosomethingA();
methodB();
}
# PROPAGATION_REQUIRES_NEW // methodB的事务传播属性为PROPAGATION_REQUIRES_NEW
methodB(){
dosomethingB();
}
如果调用methodA时,如果没有处在事务中,当调用methodB时,事务管理器会打开一个新事务TsB。如果methodA处于一个事务TsA中,在调用methodB时,事务管理器会将methodA的事务TsA挂起,再打开一个新事务TsB,当methodB运行完成后,再恢复methodA的事务TsA。需要说明的是TsA和TsB互不影响,也就是说TsB的回滚并不能影响TsA,同样TsA的回滚也不影响TsB
4. PROPAGATION_NOT_SUPPORTED 总是非事务地执行,并挂起任何存在的事务
methodA(){
dosomethingA();
methodB();
}
# PROPAGATION_NOT_SUPPORTED // methodB的事务传播属性为PROPAGATION_NOT_SUPPORTED
methodB(){
dosomethingB();
}
如果调用methodA时,如果没有处在事务中,当调用methodB时,没有事务保护的运行。如果methodA处于一个事务TsA中,在调用methodB时,事务管理器会将methodA的事务TsA挂起,没有事务保护的执行methodB,完成后,再恢复methodA的事务TsA
5. PROPAGATION_NEVER 总是非事务地执行,如果存在一个活动事务,则抛出异常
methodA(){
dosomethingA();
methodB();
}
# PROPAGATION_NEVER // methodB的事务传播属性为PROPAGATION_NEVER
methodB(){
dosomethingB();
}
如果调用methodA时,如果没有处在事务中,当调用methodB时,没有事务保护的运行。如果methodA处于一个事务TsA中,在调用methodB时,事务管理器抛出异常
6. PROPAGATION_MANDATORY 如果已经存在一个事务,支持当前事务。如果没有一个活动的事务,则抛出异常
methodA(){
dosomethingA();
methodB();
}
# PROPAGATION_MANDATORY // methodB的事务传播属性为PROPAGATION_MANDATORY
methodB(){
dosomethingB();
}
如果调用methodA时,如果没有处在事务中,当调用methodB时,事务管理器抛出异常。如果methodA处于一个事务TsA中,在调用methodB时,methodB会自动加入到已有的事务TsA