TransactionDefinition
public erface TransactionDefinition {
getPropagationBehavior;
getIsolationLevel;
getTimeout;
boolean isReadOnly;
}
getTimeout思路方法它返回事务必须在多少秒内完成 isReadOnly,事务是否只读事务管理器能够根据这个返回值进行优化确保事务是只读
getIsolationLevel思路方法返回事务隔离级别事务管理器根据它来控制另外个事务可以看到本事务内哪些数据
在TransactionDefinition接口中定义了 5个区别事务隔离级别ISOLATION_DEFAULT 这是个PlatfromTransactionManager默认隔离级别使用数据库默认事务隔离级别.另外 4个和JDBC隔离级别相对应ISOLATION_READ_UNCOMMITTED 这是事务最低隔离级别它充许别外个事务可以看到这个事务未提交数据这种隔离级别会产生脏读不可重复读和幻像读
在TransactionDefinition接口中共有7种选项可用:
PROPAGATION_REQUIRED:支持当前事务如果当前没有事务就新建个事务这是最常见选择
PROPAGATION_SUPPORTS:支持当前事务如果当前没有事务就以非事务方式执行
PROPAGATION_MANDATORY:支持当前事务如果当前没有事务就抛出异常
PROPAGATION_REQUIRES_NEW:新建事务如果当前存在事务把当前事务挂起
PROPAGATION_NOT_SUPPORTED:以非事务方式执行操作如果当前存在事务就把当前事务挂起
PROPAGATION_NEVER:以非事务方式执行如果当前存在事务则抛出异常
PROPAGATION_NESTED:支持当前事务新增Savepo点和当前事务同步提交或回滚
现在结合个例子应用以上各种传播属性来进行介绍说明:首先声明两个bean:ServiceA和ServiceB其中ServiceB被引用;
ServiceA {
void methodA {
ServiceB.methodB;
}
}
ServiceB {
void methodB {
}
}
接下来我们就分析下:PROPAGATION_REQUIRED
加入当前正要执行事务不在另外个事务里那么就起个新事务;比如说ServiceB.methodB事务级别定义为PROPAGATION_REQUIRED, 那么由于执行ServiceA.methodA时候 ServiceA.methodA已经起了事务这时ServiceB.methodBServiceB.methodB看到自己已经运行在ServiceA.methodA 事务内部就不再起新事务而假如ServiceA.methodA运行时候发现自己没有在事务中他就会为自己分配个事务 这样在ServiceA.methodA或者在ServiceB.methodB内任何地方出现异常事务都会被回滚即使ServiceB.methodB事务已经被 提交但是ServiceA.methodA在接下来fail要回滚ServiceB.methodB也要回滚
PROPAGATION_SUPPORTS
如果当前在事务中即以事务形式运行如果当前不再个事务中那么就以非事务形式运行
PROPAGATION_MANDATORY
必须在个事务中运行也就是说他只能被个父事务否则他就要抛出异常
PROPAGATION_REQUIRES_NEW
比如我们设计ServiceA.methodA事务级别为PROPAGATION_REQUIREDServiceB.methodB事务级别为PROPAGATION_REQUIRES_NEW 那么当执行到ServiceB.methodB时候ServiceA.methodA所在事务就会挂起ServiceB.methodB会起个新事务等待ServiceB.methodB事务完成以后 他才继续执行他和PROPAGATION_REQUIRED 事务区别在于事务回滚程度了ServiceB.methodB是新起个事务那么就是存在 两个区别事务如果ServiceB.methodB已经提交那么ServiceA.methodA失败回滚ServiceB.methodB是不会回滚如果ServiceB.methodB失败回滚 如果他抛出异常被ServiceA.methodA捕获ServiceA.methodA事务仍然可能提交
PROPAGATION_NOT_SUPPORTED
当前不支持事务比如ServiceA.methodA事务级别是PROPAGATION_REQUIRED 而ServiceB.methodB事务级别是PROPAGATION_NOT_SUPPORTED 那么当执行到ServiceB.methodB时ServiceA.methodA事务挂起而他以非事务状态运行完再继续ServiceA.methodA事务 网管联盟bitsCN_com
PROPAGATION_NEVER
不能在事务中运行假设ServiceA.methodA事务级别是PROPAGATION_REQUIRED 而ServiceB.methodB事务级别是PROPAGATION_NEVER 那么ServiceB.methodB就要抛出异常了
PROPAGATION_NESTED
理解Nested关键是savepo他和PROPAGATION_REQUIRES_NEW区别是PROPAGATION_REQUIRES_NEW另起个事务将会和他父事务相互独立 而Nested事务和他父事务是相依他提交是要等和他父事务块提交也就是说如果父事务最后回滚他也要回滚 而Nested事务好处也是他有个savepo:
ServiceA {
void methodA {
try {
ServiceB.methodB;
} catch (Exception e) {
ServiceC.methodC;
}
}
}
也就是说ServiceB.methodB失败回滚那么ServiceA.methodA会回滚到savepo点上ServiceA.methodA可以选择另外个分支比如 ServiceC.methodC继续执行来尝试完成自己事务;但是这个事务并没有在EJB标准中定义
最新评论