📄 java开源笔记:spring源代码解析.htm
字号:
使用的是Spring定义的PlatformTransactionManager同时实现了回调接口,我们通过其回调函数完成事务处理,就像我们使用编程式事务处理一样。<BR
style="BACKGROUND-COLOR: rgb(255,255,102)"></SPAN>try {<BR>Object result =
((CallbackPreferringPlatformTransactionManager)
getTransactionManager()).execute(txAttr,<BR>new TransactionCallback() {<BR><SPAN
style="BACKGROUND-COLOR: rgb(255,255,255)">public Object
doInTransaction(TransactionStatus status) {<BR>//同样的需要一个TransactonInfo<BR
style="BACKGROUND-COLOR: rgb(255,255,255)"></SPAN><SPAN
style="BACKGROUND-COLOR: rgb(255,255,255)"><SPAN
style="BACKGROUND-COLOR: rgb(255,255,102)">TransactionInfo txInfo =
prepareTransactionInfo(txAttr, joinpointIdentification,
status);</SPAN></SPAN><BR style="BACKGROUND-COLOR: rgb(255,255,102)"><SPAN
style="BACKGROUND-COLOR: rgb(255,255,255)">try {</SPAN><BR
style="BACKGROUND-COLOR: rgb(255,255,255)"><SPAN
style="BACKGROUND-COLOR: rgb(255,255,255)"><SPAN
style="BACKGROUND-COLOR: rgb(255,255,102)">return
invocation.proceed();</SPAN></SPAN><BR
style="BACKGROUND-COLOR: rgb(255,255,102)"><SPAN
style="BACKGROUND-COLOR: rgb(255,255,255)">}</SPAN><BR
style="BACKGROUND-COLOR: rgb(255,255,255)"><SPAN
style="BACKGROUND-COLOR: rgb(255,255,255)"></SPAN>.....这里省去了异常处理和事务信息的清理代码<BR>});<BR>...........<BR>}<BR>}<BR>这里面涉及到事务的创建,我们可以在TransactionAspectSupport实现的事务管理代码:<BR>protected
TransactionInfo createTransactionIfNecessary(<BR>TransactionAttribute txAttr,
final String joinpointIdentification) {<BR><BR>// If no name specified, apply
method identification as transaction name.<BR>if (txAttr != null &&
txAttr.getName() == null) {<BR>txAttr = new
DelegatingTransactionAttribute(txAttr) {<BR>public String getName() {<BR>return
joinpointIdentification;<BR>}<BR>};<BR>}<BR><BR>TransactionStatus status =
null;<BR>if (txAttr != null)
{<BR>//这里使用了我们定义好的事务配置信息,有事务管理器来创建事务,同时返回TransactionInfo<BR><SPAN
style="BACKGROUND-COLOR: rgb(255,255,102)">status =
getTransactionManager().getTransaction(txAttr);</SPAN><BR
style="BACKGROUND-COLOR: rgb(255,255,102)">}<BR><SPAN
style="BACKGROUND-COLOR: rgb(255,255,102)">return prepareTransactionInfo(txAttr,
joinpointIdentification, status);</SPAN><BR
style="BACKGROUND-COLOR: rgb(255,255,102)">}<BR>首先通过TransactionManager得到需要的事务,事务的创建根据我们定义的事务配置决定,在AbstractTransactionManager中给出一个标准的创建过程,当然创建什么样的事务还是需要具体的PlatformTransactionManager来决定,但这里给出了创建事务的模板:<BR><SPAN><SPAN></SPAN></SPAN>public
final TransactionStatus getTransaction(TransactionDefinition definition) throws
TransactionException {<BR>Object transaction =
doGetTransaction();<BR>......<BR><BR>if (definition == null)
{<BR>//如果事务信息没有被配置,我们使用Spring默认的配置方式<BR>definition = new
DefaultTransactionDefinition();<BR>}<BR><BR>if
(isExistingTransaction(transaction)) {<BR>// Existing transaction found ->
check propagation behavior to find out how to behave.<BR>return
handleExistingTransaction(definition, transaction, debugEnabled);<BR>}<BR><BR>//
Check definition settings for new
transaction.<BR>//下面就是使用配置信息来创建我们需要的事务;比如传播属性和同步属性等<BR>//最后把创建过程中的信息收集起来放到TransactionStatus中返回;
<BR>if (definition.getTimeout() < TransactionDefinition.TIMEOUT_DEFAULT)
{<BR>throw new InvalidTimeoutException("Invalid transaction timeout",
definition.getTimeout());<BR>}<BR><BR>// No existing transaction found ->
check propagation behavior to find out how to behave.<BR>if
(definition.getPropagationBehavior() ==
TransactionDefinition.PROPAGATION_MANDATORY) {<BR>throw new
IllegalTransactionStateException(<BR>"Transaction propagation 'mandatory' but no
existing transaction found");<BR>}<BR>else if
(definition.getPropagationBehavior() ==
TransactionDefinition.PROPAGATION_REQUIRED
||<BR>definition.getPropagationBehavior() ==
TransactionDefinition.PROPAGATION_REQUIRES_NEW
||<BR>definition.getPropagationBehavior() ==
TransactionDefinition.PROPAGATION_NESTED) {<BR><SPAN
style="BACKGROUND-COLOR: rgb(255,255,102)">//这里是事务管理器创建事务的地方,并将创建过程中得到的信息放到TransactionStatus中去,包括创建出来的事务<BR>doBegin(transaction,
definition);</SPAN><BR style="BACKGROUND-COLOR: rgb(255,255,102)">boolean
newSynchronization = (getTransactionSynchronization() !=
SYNCHRONIZATION_NEVER);<BR><SPAN
style="BACKGROUND-COLOR: rgb(255,255,102)">return
newTransactionStatus(definition, transaction, true, newSynchronization,
debugEnabled, null);</SPAN><BR
style="BACKGROUND-COLOR: rgb(255,255,102)">}<BR>else {<BR>boolean
newSynchronization = (getTransactionSynchronization() ==
SYNCHRONIZATION_ALWAYS);<BR><SPAN
style="BACKGROUND-COLOR: rgb(255,255,102)">return
newTransactionStatus(definition, null, false, newSynchronization, debugEnabled,
null);</SPAN><BR
style="BACKGROUND-COLOR: rgb(255,255,102)">}<BR>}<BR><BR><BR>接着通过调用<SPAN
style="BACKGROUND-COLOR: rgb(255,255,102)">prepareTransactionInfo<SPAN
style="BACKGROUND-COLOR: rgb(255,255,255)">完成事务创建的准备,创建过程中得到的信息存储在TransactionInfo对象中进行传递同时把信息和当前线程绑定;<BR></SPAN><SPAN
style="BACKGROUND-COLOR: rgb(255,255,255)">protected TransactionInfo
prepareTransactionInfo(</SPAN><BR
style="BACKGROUND-COLOR: rgb(255,255,255)"><SPAN
style="BACKGROUND-COLOR: rgb(255,255,255)">TransactionAttribute txAttr, String
joinpointIdentification, TransactionStatus status) {</SPAN><BR
style="BACKGROUND-COLOR: rgb(255,255,255)"><BR
style="BACKGROUND-COLOR: rgb(255,255,255)"><SPAN
style="BACKGROUND-COLOR: rgb(255,255,102)">TransactionInfo txInfo = new
TransactionInfo(txAttr, joinpointIdentification);</SPAN><BR
style="BACKGROUND-COLOR: rgb(255,255,102)"><SPAN
style="BACKGROUND-COLOR: rgb(255,255,255)">if (txAttr != null) {</SPAN><BR
style="BACKGROUND-COLOR: rgb(255,255,255)"><SPAN
style="BACKGROUND-COLOR: rgb(255,255,255)">.....</SPAN><BR
style="BACKGROUND-COLOR: rgb(255,255,255)"><SPAN
style="BACKGROUND-COLOR: rgb(255,255,255)">//
同样的需要把在getTransaction中得到的TransactionStatus放到TransactionInfo中来。<BR
style="BACKGROUND-COLOR: rgb(255,255,255)"></SPAN><SPAN
style="BACKGROUND-COLOR: rgb(255,255,255)"><SPAN
style="BACKGROUND-COLOR: rgb(255,255,102)">txInfo.newTransactionStatus(status);</SPAN></SPAN><BR
style="BACKGROUND-COLOR: rgb(255,255,102)"><SPAN
style="BACKGROUND-COLOR: rgb(255,255,255)">}</SPAN><BR
style="BACKGROUND-COLOR: rgb(255,255,255)"><SPAN
style="BACKGROUND-COLOR: rgb(255,255,255)">else {</SPAN><BR
style="BACKGROUND-COLOR: rgb(255,255,255)"><SPAN
style="BACKGROUND-COLOR: rgb(255,255,255)"></SPAN><SPAN
style="BACKGROUND-COLOR: rgb(255,255,255)">.......<BR>}</SPAN><BR
style="BACKGROUND-COLOR: rgb(255,255,255)"><BR
style="BACKGROUND-COLOR: rgb(255,255,255)"><SPAN
style="BACKGROUND-COLOR: rgb(255,255,255)"></SPAN><SPAN
style="BACKGROUND-COLOR: rgb(255,255,255)">// 绑定事务创建信息到当前线程</SPAN><BR
style="BACKGROUND-COLOR: rgb(255,255,255)"><SPAN
style="BACKGROUND-COLOR: rgb(255,255,102)">txInfo.bindToThread();</SPAN><BR
style="BACKGROUND-COLOR: rgb(255,255,102)"><SPAN
style="BACKGROUND-COLOR: rgb(255,255,102)">return txInfo;</SPAN><BR
style="BACKGROUND-COLOR: rgb(255,255,102)"><SPAN
style="BACKGROUND-COLOR: rgb(255,255,255)">}</SPAN><BR
style="BACKGROUND-COLOR: rgb(255,255,255)"></SPAN>将创建事务的信息返回,然后看到其他的事务管理代码:<BR>protected
void commitTransactionAfterReturning(TransactionInfo txInfo) {<BR>if (txInfo !=
null && txInfo.hasTransaction()) {<BR>if (logger.isDebugEnabled())
{<BR>logger.debug("Invoking commit for transaction on " +
txInfo.getJoinpointIdentification());<BR>}<BR><SPAN
style="BACKGROUND-COLOR: rgb(255,255,102)">this.transactionManager.commit(txInfo.getTransactionStatus());</SPAN><BR
style="BACKGROUND-COLOR: rgb(255,255,102)">}<BR>}<BR>通过transactionManager对事务进行处理,包括异常抛出和正常的提交事务,具体的事务管理器由用户程序设定。<BR>protected
void completeTransactionAfterThrowing(TransactionInfo txInfo, Throwable ex)
{<BR>if (txInfo != null && txInfo.hasTransaction()) {<BR>if
(txInfo.transactionAttribute.rollbackOn(ex)) {<BR>......<BR>try {<BR><SPAN
style="BACKGROUND-COLOR: rgb(255,255,102)">this.transactionManager.rollback(txInfo.getTransactionStatus());</SPAN><BR
style="BACKGROUND-COLOR: rgb(255,255,102)">}<BR>..........<BR>}<BR>else
{<BR>.........<BR>try {<BR><SPAN
style="BACKGROUND-COLOR: rgb(255,255,102)">this.transactionManager.commit(txInfo.getTransactionStatus());</SPAN><BR
style="BACKGROUND-COLOR: rgb(255,255,102)">}<BR>...........<BR>}<BR><BR>protected
void commitTransactionAfterReturning(TransactionInfo txInfo) {<BR>if (txInfo !=
null && txInfo.hasTransaction()) {<BR><SPAN
style="BACKGROUND-COLOR: rgb(255,255,102)">......<BR>this.transactionManager.commit(txInfo.getTransactionStatus());</SPAN><BR
style="BACKGROUND-COLOR: rgb(255,255,102)">}<BR>}<BR>Spring通过以上代码对transactionManager进行事务处理的过程进行了AOP包装,到这里我们看到为了方便客户实现声明式的事务处理,Spring还是做了许多工作的。如果说使用编程式事务处理,过程其实比较清楚,我们可以参考书中的例子:<BR>TransactionDefinition
td = new DefaultTransactionDefinition();<BR>TransactionStatus status =
transactionManager.getTransaction(td);<BR>try{<BR>......//这里是我们的业务方法<BR>}catch
(ApplicationException e) {<BR>transactionManager.rollback(status);<BR>throw
e<BR>}<BR><SPAN
style="BACKGROUND-COLOR: rgb(255,255,102)">transactionManager.commit(status);</SPAN><BR>........<BR>我们看到这里选取了默认的事务配置DefaultTransactionDefinition,同时在创建事物的过程中得到TransactionStatus,然后通过直接调用事务管理器的相关方法就能完成事务处理。<BR>声明式事务处理也同样实现了类似的过程,只是因为采用了声明的方法,需要增加对属性的读取处理,并且需要把整个过程整合到Spring
AOP框架中和IoC容器中去的过程。<BR>下面我们选取一个具体的transactionManager -
DataSourceTransactionManager来看看其中事务处理的实现:<BR>同样的通过使用AbstractPlatformTransactionManager使用模板方法,这些都体现了对具体平台相关的事务管理器操作的封装,比如commit:<BR>public
final void commit(TransactionStatus status) throws TransactionException
{<BR>......<BR>DefaultTransactionStatus defStatus = (DefaultTransactionStatus)
status;<BR>if (defStatus.isLocalRollbackOnly()) {<BR>...... <SPAN
style="BACKGROUND-COLOR: rgb(255,255,102)"><BR>processRollback(defStatus);</SPAN><BR
style="BACKGROUND-COLOR: rgb(255,255,102)">return;<BR>}<BR><SPAN
style="BACKGROUND-COLOR: rgb(255,255,102)">.......<BR>processRollback(defStatus);</SPAN><BR
style="BACKGROUND-COLOR: rgb(255,255,102)">......<BR>}<BR><BR><SPAN
style="BACKGROUND-COLOR: rgb(255,255,102)">processCommit(defStatus);</SPAN><BR
style="BACKGROUND-COLOR: rgb(255,255,102)">}<BR>通过对TransactionStatus的具体状态的判断,来决定具体的事务处理:<BR>private
void processCommit(DefaultTransactionStatus status) throws TransactionException
{<BR>try {<BR>boolean beforeCompletionInvoked = false;<BR>try
{<BR>triggerBeforeCommit(status);<BR>triggerBeforeCompletion(status);<BR>beforeCompletionInvoked
= true;<BR>boolean globalRollbackOnly = false;<BR>if (status.isNewTransaction()
|| isFailEarlyOnGlobalRollbackOnly()) {<BR>globalRollbackOnly =
status.isGlobalRollbackOnly();<BR>}<BR>if (status.hasSavepoint())
{<BR>........<BR>status.releaseHeldSavepoint();<BR>}<BR>else if
(status.isNewTransaction()) {<BR><SPAN
style="BACKGROUND-COLOR: rgb(255,255,102)">......<BR>doCommit(status);</SPAN><BR
style="BACKGROUND-COLOR: rgb(255,255,102)">}<BR>.........<BR>}<BR>这些模板方法的实现由具体的transactionManager来实现,比如在DataSourceTransactionManager:<BR>protected
void doCommit(DefaultTransactionStatus status)
{<BR>//这里得到存在TransactionInfo中已经创建好的事务<BR>DataSourceTransactionObject txObject =
(DataSourceTransactionObject)
status.getTransaction();<BR><BR>//这里得到和事务绑定的数据库连接<BR>Connection con =
txObject.getConnectionHolder().getConnection();<BR>........<BR>try
{<BR>//这里通过数据库连接来提交事务<BR><SPAN
style="BACKGROUND-COLOR: rgb(255,255,102)">con.commit();</SPAN><BR
style="BACKGROUND-COLOR: rgb(255,255,102)">}<BR>.......<BR>}<BR><BR>protected
void doRollback(DefaultTransactionStatus status)
{<BR>DataSourceTransactionObject txObject = (DataSourceTransactionObject)
status.getTransaction();<BR>Connection con =
txObject.getConnectionHolder().getConnection();<BR>if (status.isDebug())
{<BR>logger.debug("Rolling back JDBC transaction on Connection [" + con +
"]");<BR>}<BR>try {<BR>//这里通过数据库连接来回滚事务<BR><SPAN
style="BACKGROUND-COLOR: rgb(255,255,102)">con.rollback();</SPAN><BR
style="BACKGROUND-COLOR: rgb(255,255,102)">}<BR>catch (SQLException ex)
{<BR>throw new TransactionSystemException("Could not roll back JDBC
transaction",
ex);<BR>}<BR>}<BR>我们看到在DataSourceTransactionManager中最后还是交给connection来实现事务的提交和rollback。整个声明式事务处理是事务处理在Spring
AOP中的应用,我们看到了一个很好的使用Spring
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -