@@ -90,7 +90,7 @@ public void ExecuteWorkInIsolation(ISessionImplementor session, IIsolatedWork wo
9090 }
9191 }
9292
93- public class DistributedTransactionContext : ITransactionContext , IEnlistmentNotification
93+ public class DistributedTransactionContext : ITransactionContext , IEnlistmentNotification , IPromotableSinglePhaseNotification
9494 {
9595 public System . Transactions . Transaction AmbientTransation { get ; set ; }
9696 public bool ShouldCloseSessionOnDistributedTransactionCompleted { get ; set ; }
@@ -104,6 +104,79 @@ public DistributedTransactionContext(ISessionImplementor sessionImplementor, Sys
104104 IsInActiveTransaction = true ;
105105 }
106106
107+ #region IPromotableSinglePhaseNotification Members
108+
109+ void IPromotableSinglePhaseNotification . Initialize ( )
110+ {
111+ logger . Error ( "promotable single-phase transaction initialize" ) ;
112+ using ( new SessionIdLoggingContext ( sessionImplementor . SessionId ) )
113+ {
114+ try
115+ {
116+ using ( var tx = new TransactionScope ( AmbientTransation ) )
117+ {
118+ sessionImplementor . BeforeTransactionCompletion ( null ) ;
119+ if ( sessionImplementor . FlushMode != FlushMode . Manual && sessionImplementor . ConnectionManager . IsConnected )
120+ {
121+ using ( sessionImplementor . ConnectionManager . FlushingFromDtcTransaction )
122+ {
123+ logger . Debug ( string . Format ( "[session-id={0}] Flushing from Dtc Transaction" , sessionImplementor . SessionId ) ) ;
124+ sessionImplementor . Flush ( ) ;
125+ }
126+ }
127+ logger . Debug ( "prepared for promotable single-phase transaction" ) ;
128+
129+ tx . Complete ( ) ;
130+ }
131+ }
132+ catch ( Exception exception )
133+ {
134+ logger . Error ( "promotable single-phase transaction prepare phase failed" , exception ) ;
135+ }
136+ }
137+ }
138+
139+ void IPromotableSinglePhaseNotification . SinglePhaseCommit ( SinglePhaseEnlistment singlePhaseEnlistment )
140+ {
141+ using ( new SessionIdLoggingContext ( sessionImplementor . SessionId ) )
142+ {
143+ try
144+ {
145+ sessionImplementor . BeforeTransactionCompletion ( null ) ;
146+ logger . Debug ( "committing promotable single-phase transaction" ) ;
147+ // we have nothing to do here, since it is the actual
148+ // DB connection that will commit the transaction
149+ singlePhaseEnlistment . Committed ( ) ;
150+ IsInActiveTransaction = false ;
151+ }
152+ catch ( Exception exception )
153+ {
154+ logger . Error ( "promotable single-phase transaction prepare phase failed" , exception ) ;
155+ singlePhaseEnlistment . Aborted ( exception ) ;
156+ }
157+ }
158+ }
159+
160+ void IPromotableSinglePhaseNotification . Rollback ( SinglePhaseEnlistment singlePhaseEnlistment )
161+ {
162+ using ( new SessionIdLoggingContext ( sessionImplementor . SessionId ) )
163+ {
164+ logger . Debug ( "rolled back promotable single-phase transaction" ) ;
165+ // Currently AfterTransactionCompletion is called by the handler for the TransactionCompleted event.
166+ //sessionImplementor.AfterTransactionCompletion(false, null);
167+ singlePhaseEnlistment . Done ( ) ;
168+ IsInActiveTransaction = false ;
169+ }
170+ }
171+
172+ byte [ ] ITransactionPromoter . Promote ( )
173+ {
174+ logger . Error ( "promotable single-phase transaction promote not implemented" ) ;
175+ throw new TransactionPromotionException ( "Not implemented" ) ;
176+ }
177+
178+ #endregion
179+
107180 #region IEnlistmentNotification Members
108181
109182 void IEnlistmentNotification . Prepare ( PreparingEnlistment preparingEnlistment )
@@ -181,4 +254,4 @@ public void Dispose()
181254 }
182255 }
183256 }
184- }
257+ }
0 commit comments