1,使用DataSourceTransactionManager(jdbc事務)
???
???使用DataSourceTransactionManager,只要設置一個dataSource就可以,如下面代碼所示
???實現(xiàn)中用到了上一篇文章“spring對jdbc的封裝”中對TransactionSynchronizationManager、ConnectionHolde和DataSourceUtilsr的介紹,應用代碼中只要在事務操作中connection是通過DataSourceUtils獲取,就能保證事務的執(zhí)行。
???主要類的結(jié)構(gòu)為:
public?class?DataSourceTransactionManager?extends?AbstractPlatformTransactionManager?implements?InitializingBean???
public?abstract?class?AbstractPlatformTransactionManager?implements?PlatformTransactionManager????AbstractPlatformTransactionManager提供各種PlatformTransactionManager通用的template method,下面代碼中訪問級別為protected的方法為DataSourceTransactionManager對jdbc 事務的具體實現(xiàn),
1.1,getTransaction實現(xiàn)(AbstractPlatformTransactionManager),注意事務的傳播類型和TransactionStatus構(gòu)造函數(shù)中實參的定義。

/**?*//**
?????*?This?implementation?of?getTransaction?handles?propagation?behavior.
?????*?Delegates?to?doGetTransaction,?isExistingTransaction,?doBegin.
?????*?@see?#doGetTransaction
?????*?@see?#isExistingTransaction
?????*?@see?#doBegin
?????*/

????public?final?TransactionStatus?getTransaction(TransactionDefinition?definition)?throws?TransactionException?
{
????????Object?transaction?=?doGetTransaction();

????????//?cache?to?avoid?repeated?checks
????????boolean?debugEnabled?=?logger.isDebugEnabled();


????????if?(debugEnabled)?
{
????????????logger.debug("Using?transaction?object?["?+?transaction?+?"]");
????????}


????????if?(definition?==?null)?
{
????????????//?use?defaults
????????????definition?=?new?DefaultTransactionDefinition();
????????}
????????????????//如果transaction已經(jīng)存在(已經(jīng)調(diào)用過TransactionSynchronizationManager.bindResource(
),
????????????????//控制事務傳播類型

????????if?(isExistingTransaction(transaction))?
{

????????????????????/**?*//**
?????????????????????*?Execute?non-transactionally,?throw?an?exception?if?a?transaction?exists.
?????????????????????*?Analogous?to?EJB?transaction?attribute?of?the?same?name.
?????????????????????*/

????????????if?(definition.getPropagationBehavior()?==?TransactionDefinition.PROPAGATION_NEVER)?
{
????????????????throw?new?IllegalTransactionStateException(
????????????????????????"Transaction?propagation?'never'?but?existing?transaction?found");
????????????}

????????????????????????/**?*//**
?????????????????????????*?Execute?non-transactionally,?suspend?the?current?transaction?if?one?exists.
?????????????????????????*?Analogous?to?EJB?transaction?attribute?of?the?same?name.
?????????????????????????*/

????????????if?(definition.getPropagationBehavior()?==?TransactionDefinition.PROPAGATION_NOT_SUPPORTED)?
{

????????????????if?(debugEnabled)?
{
????????????????????logger.debug("Suspending?current?transaction");
????????????????}
????????????????Object?suspendedResources?=?suspend(transaction);
????????????????boolean?newSynchronization?=?(this.transactionSynchronization?==?SYNCHRONIZATION_ALWAYS);
????????????????return?newTransactionStatus(
????????????????????????null,?false,?newSynchronization,?definition.isReadOnly(),?debugEnabled,?suspendedResources);
????????????}

????????????????????????/**?*//**
?????????????????????????*?Create?a?new?transaction,?suspend?the?current?transaction?if?one?exists.
?????????????????????????*?Analogous?to?EJB?transaction?attribute?of?the?same?name.
?????????????????????????*/

????????????else?if?(definition.getPropagationBehavior()?==?TransactionDefinition.PROPAGATION_REQUIRES_NEW)?
{

????????????????if?(debugEnabled)?
{
????????????????????logger.debug("Creating?new?transaction,?suspending?current?one");
????????????????}
????????????????Object?suspendedResources?=?suspend(transaction);
????????????????doBegin(transaction,?definition);
????????????????boolean?newSynchronization?=?(this.transactionSynchronization?!=?SYNCHRONIZATION_NEVER);
????????????????return?newTransactionStatus(
????????????????????????transaction,?true,?newSynchronization,?definition.isReadOnly(),?debugEnabled,?suspendedResources);
????????????}

????????????????????????/**?*//**
?????????????????????????*?Execute?within?a?nested?transaction?if?a?current?transaction?exists,
?????????????????????????*?behave?like?PROPAGATION_REQUIRED?else.?There?is?no?analogous?feature?in?EJB.
?????????????????????????*/

????????????else?if?(definition.getPropagationBehavior()?==?TransactionDefinition.PROPAGATION_NESTED)?
{

????????????????if?(!isNestedTransactionAllowed())?
{
????????????????????throw?new?NestedTransactionNotSupportedException(
????????????????????????????"Transaction?manager?does?not?allow?nested?transactions?by?default?-?"?+
????????????????????????????"specify?'nestedTransactionAllowed'?property?with?value?'true'");
????????????????}

????????????????if?(debugEnabled)?
{
????????????????????logger.debug("Creating?nested?transaction");
????????????????}
????????????????boolean?newSynchronization?=?(this.transactionSynchronization?!=?SYNCHRONIZATION_NEVER);
????????????????DefaultTransactionStatus?status?=?newTransactionStatus(
????????????????????????transaction,?true,?newSynchronization,?definition.isReadOnly(),?debugEnabled,?null);

????????????????try?
{

????????????????????if?(useSavepointForNestedTransaction())?
{
????????????????????????status.createAndHoldSavepoint();
????????????????????}

????????????????????else?
{
????????????????????????doBegin(transaction,?definition);
????????????????????}
????????????????????return?status;
????????????????}

????????????????catch?(NestedTransactionNotSupportedException?ex)?
{

????????????????????if?(status.isNewSynchronization())?
{
????????????????????????TransactionSynchronizationManager.clearSynchronization();
????????????????????}
????????????????????throw?ex;
????????????????}
????????????}
????????????????????????//只要支持事務,Participating?in?existing?transaction

????????????else?
{

????????????????if?(debugEnabled)?
{
????????????????????logger.debug("Participating?in?existing?transaction");
????????????????}
????????????????boolean?newSynchronization?=?(this.transactionSynchronization?!=?SYNCHRONIZATION_NEVER);
????????????????return?newTransactionStatus(
????????????????????????transaction,?false,?newSynchronization,?definition.isReadOnly(),?debugEnabled,?null);
????????????}
????????}


????????if?(definition.getTimeout()?<?TransactionDefinition.TIMEOUT_DEFAULT)?
{
????????????throw?new?InvalidTimeoutException("Invalid?transaction?timeout",?definition.getTimeout());
????????}

????????????????/**?*//**
?????????????????*?Support?a?current?transaction,?throw?an?exception?if?none?exists.
?????????????????*?Analogous?to?EJB?transaction?attribute?of?the?same?name.
?????????????????*/

????????if?(definition.getPropagationBehavior()?==?TransactionDefinition.PROPAGATION_MANDATORY)?
{
????????????throw?new?IllegalTransactionStateException(
????????????????????"Transaction?propagation?'mandatory'?but?no?existing?transaction?found");
????????}
???????????????//Creating?new?transaction,required,nested,requires?new
????????if?(definition.getPropagationBehavior()?==?TransactionDefinition.PROPAGATION_REQUIRED?||
????????????????definition.getPropagationBehavior()?==?TransactionDefinition.PROPAGATION_REQUIRES_NEW?||

????????????definition.getPropagationBehavior()?==?TransactionDefinition.PROPAGATION_NESTED)?
{

????????????if?(debugEnabled)?
{
????????????????logger.debug("Creating?new?transaction");
????????????}
????????????doBegin(transaction,?definition);
????????????TransactionSynchronizationManager.setCurrentTransactionReadOnly(definition.isReadOnly());
????????????boolean?newSynchronization?=?(this.transactionSynchronization?!=?SYNCHRONIZATION_NEVER);
????????????return?newTransactionStatus(
????????????????????transaction,?true,?newSynchronization,?definition.isReadOnly(),?debugEnabled,?null);
????????}

????????else?
{
????????????//?"empty"?(->?no)?transaction
????????????boolean?newSynchronization?=?(this.transactionSynchronization?==?SYNCHRONIZATION_ALWAYS);
????????????return?newTransactionStatus(
????????????????????null,?false,?newSynchronization,?definition.isReadOnly(),?debugEnabled,?null);
????????}
????}???獲取ConnectionHolder的方法與JdbcTemplate中是一致的,保證同一線程獲取的connection是同一個,使事務順利執(zhí)行。

protected?Object?doGetTransaction()?
{
????????DataSourceTransactionObject?txObject?=?new?DataSourceTransactionObject();
????????txObject.setSavepointAllowed(isNestedTransactionAllowed());
????????ConnectionHolder?conHolder?=
????????????(ConnectionHolder)?TransactionSynchronizationManager.getResource(this.dataSource);
????????txObject.setConnectionHolder(conHolder);
????????return?txObject;
????}
protected?boolean?isExistingTransaction(Object?transaction)?
{
????????DataSourceTransactionObject?txObject?=?(DataSourceTransactionObject)?transaction;
????????//?Consider?a?pre-bound?connection?as?transaction.
????????return?(txObject.getConnectionHolder()?!=?null);
????}???
???以下兩個方法用于構(gòu)建特定的TransactionStatus

/**?*//**
?????*?Create?a?new?TransactionStatus?for?the?given?arguments,
?????*?initializing?transaction?synchronization?if?appropriate.
?????*/
????private?DefaultTransactionStatus?newTransactionStatus(
????????????Object?transaction,?boolean?newTransaction,?boolean?newSynchronization,

????????????boolean?readOnly,?boolean?debug,?Object?suspendedResources)?
{

????????boolean?actualNewSynchronization?=?newSynchronization?&&
????????????????!TransactionSynchronizationManager.isSynchronizationActive();

????????if?(actualNewSynchronization)?
{
????????????TransactionSynchronizationManager.initSynchronization();
????????}
????????return?new?DefaultTransactionStatus(
????????????????transaction,?newTransaction,?actualNewSynchronization,?readOnly,?debug,?suspendedResources);
????}??
???默認TransactionStatus的構(gòu)造函數(shù)

/**?*//**
?????*?Create?a?new?TransactionStatus?instance.
?????*?@param?transaction?underlying?transaction?object?that?can?hold
?????*?state?for?the?internal?transaction?implementation
?????*?@param?newTransaction?if?the?transaction?is?new,
?????*?else?participating?in?an?existing?transaction
?????*?@param?newSynchronization?if?a?new?transaction?synchronization
?????*?has?been?opened?for?the?given?transaction
?????*?@param?debug?should?debug?logging?be?enabled?for?the?handling?of?this?transaction?
?????*?Caching?it?in?here?can?prevent?repeated?calls?to?ask?the?logging?system?whether
?????*?debug?logging?should?be?enabled.
?????*/
????public?DefaultTransactionStatus(
????????Object?transaction,?boolean?newTransaction,?boolean?newSynchronization,

????????boolean?readOnly,?boolean?debug,?Object?suspendedResources)?
{

????????this.transaction?=?transaction;
????????this.newTransaction?=?newTransaction;
????????this.newSynchronization?=?newSynchronization;
????????this.readOnly?=?readOnly;
????????this.debug?=?debug;
????????this.suspendedResources?=?suspendedResources;
????}1.2,commit實現(xiàn)(AbstractPlatformTransactionManager)

/**?*//**
?????*?This?implementation?of?commit?handles?participating?in?existing
?????*?transactions?and?programmatic?rollback?requests.
?????*?Delegates?to?isRollbackOnly,?doCommit?and?rollback.
?????*?@see?org.springframework.transaction.TransactionStatus#isRollbackOnly
?????*?@see?#doCommit
?????*?@see?#rollback
?????*/

????public?final?void?commit(TransactionStatus?status)?throws?TransactionException?
{
????????DefaultTransactionStatus?defStatus?=?(DefaultTransactionStatus)?status;

????????if?(defStatus.isCompleted())?
{
????????????throw?new?IllegalTransactionStateException(
????????????????????"Transaction?is?already?completed?-?do?not?call?commit?or?rollback?more?than?once?per?transaction");
????????}

????????if?(status.isRollbackOnly())?
{

????????????if?(defStatus.isDebug())?
{
????????????????logger.debug("Transactional?code?has?requested?rollback");
????????????}
????????????rollback(status);
????????}

????????else?
{

????????????try?
{
????????????????boolean?beforeCompletionInvoked?=?false;

????????????????try?
{
????????????????????triggerBeforeCommit(defStatus);
????????????????????triggerBeforeCompletion(defStatus,?null);
????????????????????beforeCompletionInvoked?=?true;

????????????????????if?(defStatus.hasSavepoint())?
{

????????????????????????if?(defStatus.isDebug())?
{
????????????????????????????logger.debug("Releasing?transaction?savepoint");
????????????????????????}
????????????????????????defStatus.releaseHeldSavepoint();
????????????????????}

????????????????????else?if?(status.isNewTransaction())?
{
????????????????????????logger.debug("Initiating?transaction?commit");
????????????????????????doCommit(defStatus);
????????????????????}
????????????????}

????????????????catch?(UnexpectedRollbackException?ex)?
{
????????????????????//?can?only?be?caused?by?doCommit
????????????????????triggerAfterCompletion(defStatus,?TransactionSynchronization.STATUS_ROLLED_BACK,?ex);
????????????????????throw?ex;
????????????????}

????????????????catch?(TransactionException?ex)?
{
????????????????????//?can?only?be?caused?by?doCommit

????????????????????if?(isRollbackOnCommitFailure())?
{
????????????????????????doRollbackOnCommitException(defStatus,?ex);
????????????????????}

????????????????????else?
{
????????????????????????triggerAfterCompletion(defStatus,?TransactionSynchronization.STATUS_UNKNOWN,?ex);
????????????????????}
????????????????????throw?ex;
????????????????}

????????????????catch?(RuntimeException?ex)?
{

????????????????????if?(!beforeCompletionInvoked)?
{
????????????????????????triggerBeforeCompletion(defStatus,?ex);
????????????????????}
????????????????????doRollbackOnCommitException(defStatus,?ex);
????????????????????throw?ex;
????????????????}

????????????????catch?(Error?err)?
{

????????????????????if?(!beforeCompletionInvoked)?
{
????????????????????????triggerBeforeCompletion(defStatus,?err);
????????????????????}
????????????????????doRollbackOnCommitException(defStatus,?err);
????????????????????throw?err;
????????????????}
????????????????triggerAfterCompletion(defStatus,?TransactionSynchronization.STATUS_COMMITTED,?null);
????????????}

????????????finally?
{
????????????????cleanupAfterCompletion(defStatus);
????????????}
????????}
????}
protected?void?doCommit(DefaultTransactionStatus?status)?
{
????????DataSourceTransactionObject?txObject?=?(DataSourceTransactionObject)?status.getTransaction();
????????Connection?con?=?txObject.getConnectionHolder().getConnection();

????????if?(status.isDebug())?
{
????????????logger.debug("Committing?JDBC?transaction?on?connection?["?+?con?+?"]");
????????}

????????try?
{
????????????con.commit();
????????}

????????catch?(SQLException?ex)?
{
????????????throw?new?TransactionSystemException("Could?not?commit?JDBC?transaction",?ex);
????????}
????}1.3,rollback實現(xiàn)(AbstractPlatformTransactionManager)

/**?*//**
?????*?This?implementation?of?rollback?handles?participating?in?existing
?????*?transactions.?Delegates?to?doRollback?and?doSetRollbackOnly.
?????*?@see?#doRollback
?????*?@see?#doSetRollbackOnly
?????*/

????public?final?void?rollback(TransactionStatus?status)?throws?TransactionException?
{
????????DefaultTransactionStatus?defStatus?=?(DefaultTransactionStatus)?status;

????????if?(defStatus.isCompleted())?
{
????????????throw?new?IllegalTransactionStateException(
????????????????????"Transaction?is?already?completed?-?do?not?call?commit?or?rollback?more?than?once?per?transaction");
????????}

????????try?
{

????????????try?
{
????????????????triggerBeforeCompletion(defStatus,?null);

????????????????if?(defStatus.hasSavepoint())?
{

????????????????????if?(defStatus.isDebug())?
{
????????????????????????logger.debug("Rolling?back?transaction?to?savepoint");
????????????????????}
????????????????????defStatus.rollbackToHeldSavepoint();
????????????????}

????????????????else?if?(status.isNewTransaction())?
{
????????????????????logger.debug("Initiating?transaction?rollback");
????????????????????doRollback(defStatus);
????????????????}

????????????????else?if?(defStatus.getTransaction()?!=?null)?
{

????????????????????if?(defStatus.isDebug())?
{
????????????????????????logger.debug("Setting?existing?transaction?rollback-only");
????????????????????}
????????????????????doSetRollbackOnly(defStatus);
????????????????}

????????????????else?
{
????????????????????logger.warn("Should?roll?back?transaction?but?cannot?-?no?transaction?available");
????????????????}
????????????}

????????????catch?(RuntimeException?ex)?
{
????????????????triggerAfterCompletion(defStatus,?TransactionSynchronization.STATUS_UNKNOWN,?ex);
????????????????throw?ex;
????????????}

????????????catch?(Error?err)?
{
????????????????triggerAfterCompletion(defStatus,?TransactionSynchronization.STATUS_UNKNOWN,?err);
????????????????throw?err;
????????????}
????????????triggerAfterCompletion(defStatus,?TransactionSynchronization.STATUS_ROLLED_BACK,?null);
????????}

????????finally?
{
????????????cleanupAfterCompletion(defStatus);
????????}
????}
protected?void?doRollback(DefaultTransactionStatus?status)?
{
????????DataSourceTransactionObject?txObject?=?(DataSourceTransactionObject)?status.getTransaction();
????????Connection?con?=?txObject.getConnectionHolder().getConnection();

????????if?(status.isDebug())?
{
????????????logger.debug("Rolling?back?JDBC?transaction?on?connection?["?+?con?+?"]");
????????}

????????try?
{
????????????con.rollback();
????????}

????????catch?(SQLException?ex)?
{
????????????throw?new?TransactionSystemException("Could?not?roll?back?JDBC?transaction",?ex);
????????}
????}2,使用TransactionTemplate
???TransactionTemplate封裝了一個回調(diào)接口實現(xiàn)類來執(zhí)行具體的事務代碼,確保了正確的事務初始化和事務關(guān)閉過程,避免了重復編寫事務處理流程的問題。
???如果回調(diào)處理代碼拋出一個運行期異常,要么對于回調(diào)方法調(diào)用transactionStatus.setRollbackOnly()設置事務類型為只允許會滾,那么TransactionTemplate執(zhí)行事務會滾,否則事務自動提交。
???使用方法如下:
TransactionTemplate?transactionTemplate=new?TransactionTemplate(transactionStatus);
????transactionTemplate.execute(

????????new?TransactionCallback()
{

????????????public?Object?doInTransaction?(TransactionStatus?status)
{
????????????????//operations
????????????}????????????????
????????}
????}封裝代碼如下所示:

/**?*//**
?????*?Execute?the?action?specified?by?the?given?callback?object?within?a?transaction.
?????*?<p>Allows?for?returning?a?result?object?created?within?the?transaction,?i.e.
?????*?a?domain?object?or?a?collection?of?domain?objects.?A?RuntimeException?thrown
?????*?by?the?callback?is?treated?as?application?exception?that?enforces?a?rollback.
?????*?An?exception?gets?propagated?to?the?caller?of?the?template.
?????*?@param?action?callback?object?that?specifies?the?transactional?action
?????*?@return?a?result?object?returned?by?the?callback,?or?null
?????*?@throws?TransactionException?in?case?of?initialization,?rollback,?or?system?errors
?????*/

????public?Object?execute(TransactionCallback?action)?throws?TransactionException?
{
????????TransactionStatus?status?=?this.transactionManager.getTransaction(this);
????????Object?result?=?null;

????????try?
{
????????????result?=?action.doInTransaction(status);
????????}

????????catch?(RuntimeException?ex)?
{
????????????//?transactional?code?threw?application?exception?->?rollback
????????????rollbackOnException(status,?ex);
????????????throw?ex;
????????}

????????catch?(Error?err)?
{
????????????//?transactional?code?threw?error?->?rollback
????????????rollbackOnException(status,?err);
????????????throw?err;
????????}
????????this.transactionManager.commit(status);
????????return?result;
????}


????/**?*//**
?????*?Perform?a?rollback,?handling?rollback?exceptions?properly.
?????*?@param?status?object?representing?the?transaction
?????*?@param?ex?the?thrown?application?exception?or?error
?????*?@throws?TransactionException?in?case?of?a?rollback?error
?????*/

????private?void?rollbackOnException(TransactionStatus?status,?Throwable?ex)?throws?TransactionException?
{

????????if?(logger.isDebugEnabled())?
{
????????????logger.debug("Initiating?transaction?rollback?on?application?exception",?ex);
????????}

????????try?
{
????????????this.transactionManager.rollback(status);
????????}

????????catch?(RuntimeException?ex2)?
{
????????????logger.error("Application?exception?overridden?by?rollback?exception",?ex);
????????????throw?ex2;
????????}

????????catch?(Error?err)?
{
????????????logger.error("Application?exception?overridden?by?rollback?error",?ex);
????????????throw?err;
????????}
????}另外需要注意的一點是,只要事務爆出異常,則認為是無法恢復的,所以都為非受控異常。