рдкрд╣рд▓реЗ рднрд╛рдЧ рдХрд╛ рд▓рд┐рдВрдХрд▓реЗрди-рджреЗрдиред
рдЖрдкрдХреЛ рдпрд╛рдж рджрд┐рд▓рд╛ рджреВрдВ рдХрд┐ рдореИрдВ рдПрдХ рдЯреНрд░рд╛рдВрдЬреЗрдХреНрд╢рди рдореИрдХреЗрдирд┐рдЬреНрдо рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдЬрд╛ рд░рд╣рд╛ рдерд╛, рдЬреЛ рдЖрдкрдХреЛ рдХрд┐рд╕реА рдЯреНрд░рд╛рдВрдЬреИрдХреНрд╢рди рджреНрд╡рд╛рд░рд╛ рд╕рдВрд░рдХреНрд╖рд┐рдд рдмреНрд▓реЙрдХ рдХреЗ рдЕрдВрджрд░ рдХреЛрдИ рддреНрд░реБрдЯрд┐ рд╣реЛрдиреЗ рдкрд░ рдСрдкрд░реЗрд╢рдВрд╕ рдХреЗ рдмреНрд▓реЙрдХ рд╡рд╛рдкрд╕ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ рдЖрдкрдХреЛ рд░рд╛рдЬреНрдп рдХреЛ рдмрдирд╛рдП рд░рдЦрдиреЗ рдФрд░ рд░реЛрд▓рдмреИрдХ рд╕рдВрдЪрд╛рд▓рди рдХреЗ рд▓рд┐рдП рдЬрд┐рдореНрдореЗрджрд╛рд░реА рдХреЗ рдореБрджреНрджреЗ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдореИрдВ рддреБрд░рдВрдд рдХрд╣реВрдВрдЧрд╛ рдХрд┐ рдЬреЛ рдЖрд░реНрдХрд┐рдЯреЗрдХреНрдЪрд░ рдореИрдВ рдиреАрдЪреЗ рджреВрдВрдЧрд╛ рд╡рд╣ рддреБрд░рдВрдд рдореЗрд░реЗ рдкрд╛рд╕ рд╕реЗ рдирд╣реАрдВ рдирд┐рдХрд▓рд╛, рд▓реЗрдХрд┐рди рд▓реЗрдЖрдЙрдЯ рдХреЛ рдбрд┐рдЬрд╛рдЗрди рдХрд░рдиреЗ рдФрд░ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рдХрдИ рдкреНрд░рдпрд╛рд╕реЛрдВ рдХреЗ рдмрд╛рдж, рдЬрдм рддрдХ рдХрд┐ рдореБрдЭреЗ рдХреНрдпрд╛ рдирд╣реАрдВ рдорд┐рд▓рд╛ред
рд▓реЗрдирджреЗрди рдЖрд░реНрдХрд┐рдЯреЗрдХреНрдЪрд░ рдХреЛ рдЖрд╕рд╛рдиреА рд╕реЗ рд╕реНрдХреЗрд▓реЗрдмрд▓ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рдкрд╣рд▓реЗ рдХреА рддрд░рд╣ рдЗрдирд╣реЗрд░рд┐рдЯреЗрдВрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВрдЧреЗред рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ, рд╣рдо рдЯреАрдо рдкрд░ рд╣реА рд░рд╛рдЬреНрдп рдХреЛ рдмрдирд╛рдП рд░рдЦрдиреЗ рдФрд░ рд╕рд╣реЗрдЬреЗ рдЧрдП рд░рд╛рдЬреНрдп рдХреЛ рд░реЛрд▓рдмреИрдХ рдХрд░рдиреЗ рдХреА рдЬрд┐рдореНрдореЗрджрд╛рд░реА рд╕реМрдВрдкреЗрдВрдЧреЗред рдзреНрдпрд╛рди рд░рдЦреЗрдВ рдХрд┐ рд╕рднреА рдЯреАрдореЗрдВ рдЕрдирд┐рд╡рд╛рд░реНрдп рд░реВрдк рд╕реЗ рд▓реЗрди-рджреЗрди рд╡рд╛рд▓реА рдирд╣реАрдВ рд╣реИрдВред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рд░рдЬрд┐рд╕реНрдЯреНрд░реА рд╕реЗ рдкрдврд╝рдирд╛ рд▓реЗрдирджреЗрди рдХрд╛ рд╣рд┐рд╕реНрд╕рд╛ рдирд╣реАрдВ рд╣реЛ рд╕рдХрддрд╛ рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рд╕рд┐рд╕реНрдЯрдо рдореЗрдВ рдХреБрдЫ рднреА рдирд╣реАрдВ рдмрджрд▓рддрд╛ рд╣реИред рд▓реЗрдХрд┐рди рдПрдХ рд░рдЬрд┐рд╕реНрдЯреНрд░реА рдкреНрд░рд╡рд┐рд╖реНрдЯрд┐ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рд▓реЗрдирджреЗрди рдХрд╛ рд╣рд┐рд╕реНрд╕рд╛ рд╣реИред рдФрд░ рдлрд╝рд╛рдЗрд▓ рдирд┐рд░реНрдорд╛рдг рд▓реЗрдирджреЗрди рдХрд╛ рд╣рд┐рд╕реНрд╕рд╛ рд╣реИред
рдФрд░ рдЗрд╕рд▓рд┐рдП рд╣рдо рдПрдХ рдФрд░ рд╕рд╛рд░ рд╡рд░реНрдЧ TransactionalCommand рдХреА рдШреЛрд╖рдгрд╛ рдХрд░рддреЗ рд╣реИрдВ, рдЗрд╕реЗ рдХрдорд╛рдВрдб рд╡рд░реНрдЧ рд╕реЗ рд╡рд┐рд░рд╛рд╕рдд рдореЗрдВ рдорд┐рд▓рд╛ рд╣реИред
рдпрд╣ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦреЗрдЧрд╛:
public abstract class TransactionalCommand : Command { public abstract TransactionStep Do(ExecutionContext context, Transaction transaction); public abstract void Rollback(TransactionStep step); }
рдХреНрдпрд╛ рд╣реБрдЖ? рд╣рдордиреЗ рдЗрд╕реЗ рдкреНрд░рдХрд╛рд░ рдХреЗ рд▓реЗрди-рджреЗрди рдХрд╛ рдПрдХ рдФрд░ рддрд░реНрдХ рдмрддрд╛рдХрд░ рдбреВ () рд╡рд┐рдзрд┐ рдореЗрдВ рдПрдХ рдЕрдзрд┐рднрд╛рд░ рдЬреЛрдбрд╝ рджрд┐рдпрд╛ред рдореИрдВ рдереЛрдбрд╝реА рджреЗрд░ рдмрд╛рдж рдЯреНрд░рд╛рдВрдЬреИрдХреНрд╢рди рдХреНрд▓рд╛рд╕ рдХрд╛ рд╡рд░реНрдгрди рдХрд░реВрдВрдЧрд╛, рд▓реЗрдХрд┐рди рдореИрдВ рдХрд╣реВрдВрдЧрд╛ рдХрд┐ рд╕рдВрдХреНрд╖реЗрдк рдореЗрдВ рдпрд╣ рдПрдХ рд▓реЗрдирджреЗрди рд╣реИ рдЬрд┐рд╕рдХреЗ рднреАрддрд░ рдХрдорд╛рдВрдб рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред рдирдИ Do рд╡рд┐рдзрд┐ рдХрд╛ рдореБрдЦреНрдп рдЙрджреНрджреЗрд╢реНрдп (рдирд┐рд╖реНрдкрд╛рджрди, рд▓реЗрдирджреЗрди, рд▓реЗрди-рджреЗрди) рдЗрд╕ рдкреНрд░рдХрд╛рд░ рд╣реИ:
- рдирдпрд╛ рд▓реЗрди-рджреЗрди рдЪрд░рдг рдмрдирд╛рдПрдВ
- рднреМрддрд┐рдХ рд░реВрдк рд╕реЗ рд╕рд╣реЗрдЬреЗрдВ (рдбрд┐рд╕реНрдХ рдкрд░, рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ, рдЖрджрд┐) рд╕рд┐рд╕реНрдЯрдо рдХреА рд╕реНрдерд┐рддрд┐, рдпрд╛ рдмрд▓реНрдХрд┐ рдЗрд╕рдХреЗ рдЙрди рдкрд╣рд▓реБрдУрдВ рдХреЛ рдЬреЛ рдХрдорд╛рдВрдб рдирд┐рд╖реНрдкрд╛рджрд┐рдд рд╣реЛрдиреЗ рдХреЗ рдмрд╛рдж рдмрджрд▓ рдЬрд╛рдПрдВрдЧреЗ,
- рдХрдорд╛рдВрдб рдХреНрд▓рд╛рд╕ рдХреЗ Do (ExecutionContext) рд╡рд┐рдзрд┐ рдХреЛ рдХреЙрд▓ рдХрд░реЗрдВ (рдЕрд░реНрдерд╛рдд, рдореВрд▓ nontransactional рдСрдкрд░реЗрд╢рди рдХрд░реЗрдВ),
- рд╢реБрд░реБрдЖрдд рдореЗрдВ рдмрдирд╛рдпрд╛ рдЧрдпрд╛ TransactionStep рд╡рд╛рдкрд╕ рдХрд░реЗрдВред
рд╣рдордиреЗ рд░реЛрд▓рдмреИрдХ () рдкрджреНрдзрддрд┐ рдХреЛ рднреА рдЬреЛрдбрд╝рд╛, рдЬреЛ рд▓реЗрди-рджреЗрди рдХреЗ рдЪрд░рдг рдХреЛ рд╡рд╛рдкрд╕ рд▓реЗрддреА рд╣реИред
рдЗрд╕ рдкреНрд░рдХрд╛рд░, рд╣рдордиреЗ рд░рд╛рдЬреНрдп рдХреЛ рдмрдирд╛рдП рд░рдЦрдиреЗ рдФрд░ рдЯреАрдо рдХреЛ рд╕реНрд╡рдпрдВ рдЯреАрдо рдореЗрдВ рд╡рд╛рдкрд╕ рд▓рд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдЬрд┐рдореНрдореЗрджрд╛рд░реА рд╕реМрдВрдкреА, рдЬреЛ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛рдУрдВ рдХреЛ рдЗрдВрд╕реНрдЯреЙрд▓рд░ рджреНрд╡рд╛рд░рд╛ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рд▓реЗрдирджреЗрди рдЖрджреЗрд╢реЛрдВ рдХреА рд╕рд░рдгреА рдХреЛ рдЖрд╕рд╛рдиреА рд╕реЗ рдмрдврд╝рд╛рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред
рдЗрдВрд╕реНрдЯреЙрд▓рд░ рдЕрд╡рд╕рдВрд░рдЪрдирд╛ рдХреЛ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛рдУрдВ рдХреЛ рд╕рд┐рд╕реНрдЯрдо рдХреА рд╕реНрдерд┐рддрд┐ рдХреЛ рдмрдирд╛рдП рд░рдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рдВрд░рдЪрд┐рдд рднрдВрдбрд╛рд░рдг рдХреЗ рд╕рд╛рде рдкреНрд░рджрд╛рди рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП рдЬрдм рддрдХ рдХрд┐ рд▓реЗрдирджреЗрди рдкреВрд░рд╛ рди рд╣реЛ рдЬрд╛рдП рдФрд░ рдЗрд╕рдХреЗ рд▓рд┐рдП рдПрдХ рдПрдХреНрд╕реЗрд╕ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рди рд╣реЛред рддреГрддреАрдп-рдкрдХреНрд╖ рдШрдЯрдХреЛрдВ (рдЬреИрд╕реЗ рдбреЗрдЯрд╛рдмреЗрд╕, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП) рдХреА рд╕реНрдерд╛рдкрдирд╛ рдкрд░ рдЬрд┐рддрдирд╛ рд╕рдВрднрд╡ рд╣реЛ рдЙрддрдирд╛ рдХрдо рдирд┐рд░реНрднрд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдореИрдВ рд╕рд┐рд╕реНрдЯрдо рдХреА рд╕реНрдерд┐рддрд┐ рдХреЛ рдЗрдВрд╕реНрдЯреЙрд▓рд░ рдХреЗ рдХрд╛рд░реНрдп рдлрд╝реЛрд▓реНрдбрд░ рдХреЗ рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рд╕рдмрдлрд╝реЛрд▓реНрдбрд░ рдореЗрдВ рд╕рдВрдЧреНрд░рд╣реАрдд рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЗ рдПрдХ рдордирдорд╛рдиреЗ рд╕реЗрдЯ рдХреЗ рд░реВрдк рдореЗрдВ рдкреНрд░рд╕реНрддреБрдд рдХрд░рдиреЗ рдЬрд╛ рд░рд╣рд╛ рд╣реВрдВред рдлрд╝рд╛рдЗрд▓ рд╕рдВрд░рдЪрдирд╛ рдХреЛ рдЗрд╕ рддрд░рд╣ рджреЗрдЦреЛ:
%GIN_DIRECTORY%\packages\[PackageId]\transactions\[TransactionName]\steps\[StepNumber]\
рдпрд╛ рдкреЗрдбрд╝ рдХреЗ рд░реВрдк рдореЗрдВ:

рдмреБрдирд┐рдпрд╛рджреА рдврд╛рдВрдЪрд╛ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЛ рдХрдорд╛рдВрдб рдХреЛ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рд╕рд┐рд╕реНрдЯрдо рдХреА рд╕реНрдерд┐рддрд┐ рдХреЛ рдмрдЪрд╛рдиреЗ рдХреЗ рд▓рд┐рдП [StepNumber] рдлрд╝реЛрд▓реНрдбрд░реЛрдВ рдХреЛ рдкрде рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИред рдЖрдзрд╛рд░рднреВрдд рд╕рдВрд░рдЪрдирд╛ рдкреЗрдбрд╝ рдХреЗ рд╕рдВрдЧрдд рдлрд╝реЛрд▓реНрдбрд░реЛрдВ рдореЗрдВ рдЕрдиреНрдп рд╕рднреА рдбреЗрдЯрд╛ рдХреЛ рдмрдЪрд╛рддрд╛ рд╣реИ, рдЬреИрд╕реЗ рдХрд┐ рд▓реЗрдирджреЗрди рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдбреЗрдЯрд╛ рдФрд░ рдЗрд╕рдХреЗ рдЪрд░рдгред рдмреЗрд╢рдХ, рдмреБрдирд┐рдпрд╛рджреА рдврд╛рдВрдЪрд╛ рд╣реА рдЗрд╕ рдкреВрд░реЗ рдкреЗрдбрд╝ рдХреЛ рдмрдирд╛рддрд╛ рд╣реИ, рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЛ рдирд┐рдпрдорд┐рдд рдХрд╛рдо рд╕реЗ рдмрдЪрд╛рддрд╛ рд╣реИред рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рджреНрд╡рд╛рд░рд╛, рдореЗрд░рд╛ рдорддрд▓рдм рд╣реИ рдХрд┐ рдЗрдВрд╕реНрдЯреЙрд▓рд░ рдХреЗ рдПрдХреНрд╕рдЯреЗрдВрд╢рди рдХреЗ рдбреЗрд╡рд▓рдкрд░ред
рдпрд╣рд╛рдБ TransactionStep рд╡рд░реНрдЧ рдХрд╛ рд╡рд┐рд╡рд░рдг рджрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ:
public class TransactionStep { public const string STEPS_SUBFOLDER_NAME = @"steps"; public int StepNumber { get; set; } public string TransactionName { get; set; } public TransactionalCommand Command { get; set; } public string GetPath(ExecutionContext context) { string transactionsPath = context.ExecutedPackage.TransactionsPath; string transactionPath = Path.Combine(transactionsPath, TransactionName); string stepsPath = Path.Combine(transactionPath, STEPS_SUBFOLDER_NAME); string stepPath = Path.Combine(stepsPath, StepNumber.ToString()); if (!Directory.Exists(stepPath)) { Directory.CreateDirectory(stepPath); } return stepPath; } }
рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рдХрдХреНрд╖рд╛ рдХреЗ рд╡рд┐рд╡рд░рдг рд╕реЗ рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ, рдХрдХреНрд╖рд╛ рдХреЗ рджреЛ рдореБрдЦреНрдп рдЙрджреНрджреЗрд╢реНрдп рд╣реИрдВ:
- рдПрдХ рдлрд╝реЛрд▓реНрдбрд░ рдмрдирд╛рддрд╛ рд╣реИ рдФрд░ рдЪрд░рдг рдкреВрд░рд╛ рд╣реЛрдиреЗ рддрдХ рд╕рд┐рд╕реНрдЯрдо рдХреА рд╕реНрдерд┐рддрд┐ рдХреЛ рдмрдЪрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдлрд╝реЛрд▓реНрдбрд░ рдореЗрдВ рдкрде рджреЗрддрд╛ рд╣реИ
- рдЗрд╕реА рдЖрджреЗрд╢ рдХреА рдПрдХ рдЖрд╡реГрддреНрддрд┐ рдХреЛ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рддрд╛ рд╣реИ рддрд╛рдХрд┐ рд▓реЗрдирджреЗрди рдХрджрдо рдХреЛ рд╡рд╛рдкрд╕ рд▓рд╛рдпрд╛ рдЬрд╛ рд╕рдХреЗ
рд╣рдо рдЗрд╕ рд╡рд░реНрдЧ рд╕реЗ рдареЛрд╕ рдХрджрдореЛрдВ рдХреЗ рдЙрдкрд╡рд░реНрдЧ рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдВрдЧреЗред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП:
public class SingleFileStep: TransactionStep { public string OldFilePath { get; set; } }
рдпрд╣ рдЙрдкрд╡рд░реНрдЧ рдПрдХрд▓ рдлрд╝рд╛рдЗрд▓ рдХреЗ рд╕рд╛рде рдХрд┐рд╕реА рднреА рдСрдкрд░реЗрд╢рди рдХреЗ рд▓рд┐рдП рдЙрдкрдпреБрдХреНрдд рд╣реИ: рдПрдХ рдлрд╝рд╛рдЗрд▓ рдмрдирд╛рдПрдВ, рдПрдХ рдлрд╝рд╛рдЗрд▓ рд╣рдЯрд╛рдПрдВ, рдПрдХ рдлрд╝рд╛рдЗрд▓ рдХреЛ рд╕рдВрд╢реЛрдзрд┐рдд рдХрд░реЗрдВред рдпрд╣ рдЙрдкрд╡рд░реНрдЧ рдмрджрд▓рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рд╕реНрд░реЛрдд рдлрд╝рд╛рдЗрд▓ рдХреА рд╕рд╣реЗрдЬреА рдЧрдИ рдкреНрд░рддрд┐рд▓рд┐рдкрд┐ рдХреЛ рдкреВрд░реНрдг рдкрде рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИред
рдФрд░ рдЕрдм рд▓реЗрдирджреЗрди рд╡рд░реНрдЧ:
public class Transaction { public string TransactionName { get; set; } public TransactionState TransactionState { get; set; } public List<TransactionStep> Steps { get; set; } public Transaction() { Steps = new List<TransactionStep>(); } public T CreateStep<T>(TransactionalCommand command) where T: TransactionStep, new() { T step = new T(); int stepNumber = Steps.Count; step.StepNumber = stepNumber; step.Command = command; step.TransactionName = TransactionName; Steps.Add(step); return step; } public void Save(ExecutionContext context) { string transactionsPath = context.ExecutedPackage.TransactionsPath; string transactionPath = Path.Combine(transactionsPath, TransactionName + @"\"); Directory.CreateDirectory(transactionPath); string dataFilePath = Path.Combine(transactionPath, @"data.xml"); GinSerializer.Serialize(this, dataFilePath); } public void Rollback() { Steps.BackForEach(s => { s.Command.Rollback(s); }); } }
рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ, рд╡рд░реНрдЧ рдХреЗ рдореБрдЦреНрдп рдХрд╛рд░реНрдп рдЗрд╕ рдкреНрд░рдХрд╛рд░ рд╣реИрдВ:
- рд▓реЗрди-рджреЗрди рдХреЗ рд▓рд┐рдП рдПрдХ рдирдпрд╛ рдХрджрдо рдЬреЛрдбрд╝рдирд╛ рдФрд░ рд▓реЗрди-рджреЗрди рдХреЗ рдЪрд░рдгреЛрдВ рдХрд╛ рдХреНрд░рдо рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рдирд╛
- рдЗрд╕реА XML рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рдбрд┐рд╕реНрдХ рдкрд░ рдЯреНрд░рд╛рдВрдЬреЗрдХреНрд╢рди рд╕реЗрд╡ рдХрд░реЗрдВ
- рд░рд┐рд╡рд░реНрд╕ рдСрд░реНрдбрд░ рдореЗрдВ рд▓реЗрди-рджреЗрди рдХреЗ рд╕рднреА рдЪрд░рдгреЛрдВ рдХреЛ рд╡рд╛рдкрд╕ рдХрд░рдХреЗ рд▓реЗрди-рджреЗрди рдХреЛ рд░реЛрд▓рдмреИрдХ рдХрд░реЗрдВ
BackForEach рд╡рд┐рдзрд┐ рдПрдХ рд╡рд┐рд╕реНрддрд╛рд░ рд╡рд┐рдзрд┐ рд╣реИ рдЬрд┐рд╕реЗ рдПрдХ рдЕрд▓рдЧ рд╡рд░реНрдЧ рдореЗрдВ рд▓реЗ рдЬрд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ рддрд╛рдХрд┐ рдЕрдиреНрдп рд╡рд░реНрдЧреЛрдВ рдХреЗ рдХреЛрдб рдХреЛ рдЕрд╡реНрдпрд╡рд╕реНрдерд┐рдд рди рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХреЗред рдЦреИрд░, рд╕рд╛рдорд╛рдиреНрдп рддреМрд░ рдкрд░, рдореИрдВ рд╡рд┐рд╕реНрддрд╛рд░ рд╡рд┐рдзрд┐рдпреЛрдВ рдФрд░ рд▓реИрдореНрдмреНрдбрд╛ рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐рдпреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдкрд╕рдВрдж рдХрд░рддрд╛ рд╣реВрдВ, рдХреГрдкрдпрд╛ рдореБрдЭреЗ рдЗрд╕ рдХрдордЬреЛрд░реА рдХреЗ рд▓рд┐рдП рдХреНрд╖рдорд╛ рдХрд░реЗрдВред
рдЕрдм рд╣рдо рд╡рд░реНрдЧреЛрдВ рдореЗрдВ рд╕реЗ рдПрдХ рдХреЛ TransactionalCommand рдХреЗ рдЙрддреНрддрд░рд╛рдзрд┐рдХрд╛рд░реА рдХреЗ рд░реВрдк рдореЗрдВ рд╕рдордЭрддреЗ рд╣реИрдВ рдХрд┐ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛рдУрдВ рдХреЛ рд▓реЗрдирджреЗрди рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рдЖрджреЗрд╢реЛрдВ рдХреЛ рдХреИрд╕реЗ рд▓рд╛рдЧреВ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред
public class CreateFile: TransactionalCommand { public string SourcePath { get; set; } public string DestPath { get; set; } public override void Do(ExecutionContext context) { File.Copy(SourcePath, DestPath, true); } public override TransactionStep Do(ExecutionContext context, Transaction transaction) { SingleFileStep step = null; if (transaction != null) { step = transaction.CreateStep<SingleFileStep>(this); } if (File.Exists(DestPath)) { string rollbackFileName = Guid.NewGuid().ToString("N") + ".rlb"; string dataPath = step.GetPath(context); string rollbackFilePath = Path.Combine(dataPath, rollbackFileName); step.OldFilePath = rollbackFilePath; File.Copy(DestPath, rollbackFilePath); } Do(context); return step; } public override void Rollback(TransactionStep step) { SingleFileStep currentStep = (SingleFileStep)step; if (File.Exists(currentStep.OldFilePath)) { File.Copy(currentStep.OldFilePath, DestPath, true); } else { File.Delete(DestPath); } } }
рджреЛ рддрд░реНрдХреЛрдВ рдХреЗ рд╕рд╛рде рдбреВ () рдкрджреНрдзрддрд┐, рдЗрд╕рдХреЗ рдкрд╛рд╕ рдХрд┐рдП рдЧрдП рд▓реЗрдирджреЗрди рдХреЗ рдврд╛рдВрдЪреЗ рдХреЗ рднреАрддрд░, CreateStep <> рд╡рд┐рдзрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдПрдХ рдирдпрд╛ рд▓реЗрдирджреЗрди рдЪрд░рдг рдмрдирд╛рддрд╛ рд╣реИ, рдлрд┐рд░ рдЬрд╛рдБрдЪрддрд╛ рд╣реИ рдХрд┐ рдХреНрдпрд╛ рдлрд╝рд╛рдЗрд▓ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдЙрд╕ рдкрде рдХреЗ рд╕рд╛рде рдореМрдЬреВрдж рд╣реИ рдЬрд╣рд╛рдБ рдЗрдВрд╕реНрдЯреЙрд▓рд░ рдХреЛ рд╡рд░реНрддрдорд╛рди рдЪрд░рдг рдореЗрдВ рдПрдХ рдирдИ рдлрд╝рд╛рдЗрд▓ рдмрдирд╛рдиреА рдЪрд╛рд╣рд┐рдП, рдФрд░ рдпрджрд┐ рдлрд╝рд╛рдЗрд▓ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рд╣реИред рдпрд╣ рдЗрд╕реЗ рдПрдХ рдЕрд▓рдЧ рдирд╛рдо (рд╣рд╛рд▓рд╛рдВрдХрд┐ рдирд╛рдо рдмрджрд▓рд╛ рдирд╣реАрдВ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ) рдХреЗ рддрд╣рдд рдЗрд╕реЗ рдЗрдВрд╕реНрдЯреЙрд▓рд░ рдЗрдиреНрдлреНрд░рд╛рд╕реНрдЯреНрд░рдХреНрдЪрд░ (TransactionStep.GetPath) рджреНрд╡рд╛рд░рд╛ рдкреНрд░рджрд╛рди рдХрд┐рдП рдЧрдП рдлрд╝реЛрд▓реНрдбрд░ рдореЗрдВ рдХреЙрдкреА рдХрд░рддрд╛ рд╣реИ, рдФрд░ рдЙрд╕рдХреЗ рдмрд╛рдж рд╣реА nransransactional рдХрдорд╛рдВрдб рдХрдорд╛рдВрдбреНрд╕ рдХреЗ рд╡рд░реНрдЧ рд╕реЗ рд╡рд┐рд░рд╛рд╕рдд рдореЗрдВ рдорд┐рд▓реА рд╡рд┐рдзрд┐ рдХреЛ рдХреЙрд▓ рдХрд░рддрд╛ рд╣реИ, рдЬреЛ рдкрд░рд┐рдгрд╛рдо рдХреЗ рд░реВрдк рдореЗрдВ рд▓реМрдЯрддрд╛ рд╣реИред рдЯреНрд░рд╛рдВрд╕ рдХрджрдо рдХреА рд╢реБрд░реБрдЖрдд рдореЗрдВ tion рдХрджрдоред
рд░реЛрд▓рдмреИрдХ рд╡рд┐рдзрд┐ рдПрдХ рддрд░реНрдХ рдХреЗ рд░реВрдк рдореЗрдВ рдПрдХ рд▓реЗрдирджреЗрди рдХрджрдо рдЙрдард╛рддреА рд╣реИ, рдФрд░ рдЗрд╕рдХреА OldFilePath рд╕рдВрдкрддреНрддрд┐ рдХреА рдЬрд╛рдБрдЪ рдХрд░рдХреЗ рдлрд╝рд╛рдЗрд▓ рдХреЗ рдкреБрд░рд╛рдиреЗ рд╕рдВрд╕реНрдХрд░рдг рдХреЛ рдЧрдВрддрд╡реНрдп рдлрд╝реЛрд▓реНрдбрд░ рдореЗрдВ рдХреЙрдкреА рдХрд░ рджреЗрддреА рд╣реИ рдпрд╛ рдЧрдВрддрд╡реНрдп рдлрд╝реЛрд▓реНрдбрд░ рд╕реЗ рдлрд╝рд╛рдЗрд▓ рдХреЛ рд╣рдЯрд╛ рджреЗрддреА рд╣реИред
рд▓реЗрди-рджреЗрди рд╡рд░реНрдЧ рдХреЗ рд▓рд┐рдП рдХреЛрдб рдореЗрдВ, рдЖрдк ExecutionContext.ExecutedPackage рд╕рдВрдкрддреНрддрд┐ рдХреЛ рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ, рдЬреЛ рд╕рдВрджрд░реНрдн рдХреЗ рднреАрддрд░ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдкреИрдХреЗрдЬ рдХреЗ рд╕рдВрджрд░реНрдн рдХрд╛ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдХрд░рддрд╛ рд╣реИред рдЗрд╕ рд▓рд┐рдВрдХ рдХреЛ рдкреИрдХреЗрдЬ рдХреНрд▓рд╛рд╕ рдХреЗ рдХрдВрд╕реНрдЯреНрд░рдХреНрдЯрд░ рдХреЗ рдЕрдВрджрд░ рдЗрдирд┐рд╢рд┐рдпрд▓рд╛рдЗрдЬрд╝ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ рдкреИрдХреЗрдЬ рд╡рд░реНрдЧ рдореЗрдВ рдПрдХ TransPPath рдЧреБрдг рд╣реИ рдЬреЛ рдкреИрдХреЗрдЬ рд▓реЗрдирджреЗрди рдлрд╝реЛрд▓реНрдбрд░ рдХреЗ рд▓рд┐рдП рдкрде рдХреЛ рдЗрдВрдЧрд┐рдд рдХрд░рддрд╛ рд╣реИред
рдЗрд╕рд▓рд┐рдП, рд╣рдордиреЗ рд▓реЗрдирджреЗрди рдХреЗ рдПрдХ рдЪрд░рдг рдХреЛ рд╕рд╣реЗрдЬрдиреЗ рдФрд░ рд╡рд╛рдкрд╕ рдХрд░рдиреЗ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд┐рдпрд╛ рд╣реИред рд▓реЗрдХрд┐рди рдкреВрд░реЗ рд▓реЗрдирджреЗрди рдХреЛ рд╡рд╛рдкрд╕ рд▓реЗрдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рд░рд┐рд╡рд░реНрд╕ рдСрд░реНрдбрд░ рдореЗрдВ рд▓реЗрдирджреЗрди рдХреЗ рдЪрд░рдгреЛрдВ рдХрд╛ рдкрд╛рд▓рди рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред рдФрд░ рдЗрд╕ рдХрд╛рд░рдг рд╕реЗ рдХрд┐ рд╣рдо рдбрд┐рд╕реНрдХ рдкрд░ рдкрд╣рд▓реЗ рд╕реЗ рд╕рдВрдЧреНрд░рд╣реАрдд рд▓реЗрди-рджреЗрди рдХреЛ рд╡рд╛рдкрд╕ рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реЛрдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рд╣рдореЗрдВ рдбрд┐рд╕реНрдХ рд╕реЗ рд▓реЗрди-рджреЗрди рдХреЛ рд▓реЛрдб рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП, рдХреНрдпреЛрдВрдХрд┐ рд╣рдо рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдЬрд╛рдирддреЗ рд╣реИрдВ рдХрд┐ рдЙрдиреНрд╣реЗрдВ рдбрд┐рд╕реНрдХ рдкрд░ рдХреИрд╕реЗ рдмрдЪрд╛рдпрд╛ рдЬрд╛рдП (рджреЗрдЦреЗрдВ рд▓реЗрди-рджреЗрдиред рджреЗрдЦреЗрдВ) рд╡рд┐рдзрд┐
рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо LoadTransactions () рдкрджреНрдзрддрд┐ рдХреЛ рдкреИрдХреЗрдЬ рдХреНрд▓рд╛рд╕ рдореЗрдВ рд▓рд╛рдЧреВ рдХрд░рддреЗ рд╣реИрдВред рдХреНрд▓рд╛рд╕ рдкреИрдХреЗрдЬ рдореЗрдВ рдХреНрдпреЛрдВ? рдХреНрдпреЛрдВрдХрд┐ рдкреИрдХреЗрдЬ рдХреНрд▓рд╛рд╕ рдХрд╛ рдореБрдЦреНрдп рдЙрджреНрджреЗрд╢реНрдп рдкреИрдХреЗрдЬ рдХреЛ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рдирд╛ рд╣реИред рдФрд░ рд▓реЗрди-рджреЗрди рдПрдХ рдкреИрдХреЗрдЬ рдХреЛ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рдиреЗ рдХреА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдореЗрдВ рд╕рдЯреАрдХ рд░реВрдк рд╕реЗ рдЙрддреНрдкрдиреНрди рд╣реЛрддрд╛ рд╣реИ, рдФрд░ рдЕрдирд┐рд╡рд╛рд░реНрдп рд░реВрдк рд╕реЗ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдкреВрд░реНрдг рдкреИрдХреЗрдЬ рдХреА рд╡рд┐рд╢реЗрд╖рддрд╛ рд╣реИред рдЗрд╕ рдкреНрд░рдХрд╛рд░, рдкреИрдХреЗрдЬ рд╡рд░реНрдЧ рдореЗрдВ рд▓реЗрдирджреЗрди рдХреА рд╕реВрдЪреА рд░рдЦрдирд╛ рддрд░реНрдХрд╕рдВрдЧрдд рд╣реЛрдЧрд╛ред рдпрд╣рд╛рдБ рд▓реЗрди-рджреЗрди рд▓реЛрдбрд┐рдВрдЧ рдХреЛрдб рд╣реИ:
private void LoadTransactions() { _transactions = new List<Transaction>(); if (String.IsNullOrEmpty(TransactionsPath) || !Directory.Exists(TransactionsPath)) { return; } string[] transactionNames = Directory.GetDirectories(TransactionsPath); foreach (string name in transactionNames) { string transactionPath = Path.Combine(TransactionsPath, name); string dataFilePath = Path.Combine(transactionPath, TRANSACTIONS_DATA_FILENAME); Transaction transaction = GinSerializers.TransactionSerializer.Deserialize(dataFilePath); _transactions.Add(transaction); } }
рдпрд╣рд╛рдВ рд╕рдм рдХреБрдЫ рд╕рд░рд▓ рд╣реИ: рд╣рдореЗрдВ TransPathPath рдлрд╝реЛрд▓реНрдбрд░ рдореЗрдВ рд╕рднреА рд╕рдмрдлрд╝реЛрд▓реНрдбрд░реНрд╕ рдХреА рдПрдХ рд╕реВрдЪреА рдорд┐рд▓рддреА рд╣реИ (рдпрд╛рдж рд░рдЦреЗрдВ, рдпрд╣ рд╕рдВрдкрддреНрддрд┐ рдЗрддрдиреА рджреЗрд░ рдкрд╣рд▓реЗ рдкреИрдХреЗрдЬ рд╡рд░реНрдЧ рдореЗрдВ рджрд┐рдЦрд╛рдИ рджреА рдереА), рд╕рдмрдлрд╝реЛрд▓реНрдбрд░ рдирд╛рдореЛрдВ рдХреА рдПрдХ рд╕реВрдЪреА рд▓реЗрдирджреЗрди рдХреЗ рдирд╛рдореЛрдВ рдХреА рд╕реВрдЪреА рд╣реЛрдЧреА (рдкреИрдХреЗрдЬ рдлрд╝рд╛рдЗрд▓ рдЯреНрд░реА рдХреА рд╕рдВрд░рдЪрдирд╛ рдХреЛ рдпрд╛рдж рд░рдЦреЗрдВ), рдФрд░ рдлрд┐рд░ рдкреНрд░рддреНрдпреЗрдХ рдирд╛рдо рдХреЗ рд▓рд┐рдП рд╣рдо рдкреВрд░реНрдг рдкрде рдмрдирд╛рддреЗ рд╣реИрдВред рд▓реЗрди-рджреЗрди рдХреА data.xml рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рдФрд░ рдЕрдЧрд▓реЗ рд▓реЗрди-рджреЗрди рдореЗрдВ рдЗрд╕реЗ рдирд┐рд╖реНрдХреНрд░рд┐рдп рдХрд░ рджреЗрддрд╛ рд╣реИред рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ, рд╕реАрд░рд▓рд╛рдЗрдЬрд╝рд░ рдЕрдкрдиреЗ рд░реЛрд▓рдмреИрдХ () рддрд░реАрдХреЛрдВ рдХреЗ рд╕рд╛рде, рдЗрди рдЪрд░рдгреЛрдВ рдореЗрдВ рдиреЗрд╕реНрдЯреЗрдб рд▓реЗрди-рджреЗрди рдЪрд░рдгреЛрдВ рдФрд░ рдЖрджреЗрд╢реЛрдВ рдХреА рд╕реВрдЪреА рджреЛрдиреЛрдВ рдмрдирд╛рдПрдЧрд╛ред LoadTransactions () рд╡рд┐рдзрд┐ рдХреЛ рдкреИрдХреЗрдЬ рдХреНрд▓рд╛рд╕ рдХреЗ рдХрдВрд╕реНрдЯреНрд░рдХреНрдЯрд░ рдореЗрдВ рдХрд╣рд╛ рдЬрд╛рдПрдЧрд╛ред рдкреИрдХреЗрдЬ рдХреНрд▓рд╛рд╕ рдХреЗ рдЧреНрд░рд╛рд╣рдХреЛрдВ рдХреЛ рд▓реЗрдирджреЗрди рдХреА рд╕реВрдЪреА рдХреА рдЖрдВрддрд░рд┐рдХ рд╕рдВрд░рдЪрдирд╛ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрддрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдирд╣реАрдВ, рд╣рдо рдкреИрдХреЗрдЬ рдХреНрд▓рд╛рд╕ рдХреЗ рдЗрдВрдЯрд░рдлреЗрд╕ рдореЗрдВ рд▓реЗрдирджреЗрди рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрдИ рддрд░реАрдХреЗ рдЬреЛрдбрд╝реЗрдВрдЧреЗред
public void Rollback(string transactionName) { Transaction transaction = GetTransactionByName(transactionName); transaction.Rollback(); } public void Rollback() { foreach (Transaction transaction in _transactions) { transaction.Rollback(); } } public void AddTransaction(Transaction transaction) { _transactions.Add(transaction); }
рдЕрдм рдЖрдЗрдП рдЬрд╛рдиреЗрдВ рдХрд┐ рдкреИрдХреЗрдЬ рдХреЗ рдЕрдВрджрд░ рд▓реЗрдирджреЗрди рдХреИрд╕реЗ рдХрд░реЗрдВред рдореИрдВ рдЗрд╕ рдЫрджреНрдордХреЛрдб рдХреЗ рд╕рд╛рде рдРрд╕рд╛ рдХрд░рдирд╛ рдЪрд╛рд╣реВрдВрдЧрд╛:
PackageBody body = new PackageBody() { Command = new CommandSequence() { Commands = new Command[] { new TransactionContainer() { TransactionName = "myTransaction", Commands = new List<Command>() { new CreateFile() { SourcePath = @"D:\test\newfile.txt", DestPath = @"C:\test\folder1\file1.txt" }, new CreateFile() { SourcePath = @"D:\test\newfile.txt", DestPath = @"C:\test\folder1\file2.txt" }, new ThrowException() { Message = "Test exception" }, new CreateFile() { SourcePath = @"D:\test\newfile.txt", DestPath = @"C:\test\folder1\file3.txt" } } } } } }; PackageBuilder builder = new PackageBuilder(body); string fileName = builder.GetResult(); Package pkg = new Package(fileName); ExecutionContext ctx = pkg.Execute();
рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ, рдХрдХреНрд╖рд╛рдУрдВ рдХреА рд╕рдВрд░рдЪрдирд╛ рдореЗрдВ рдХрд╛рдлреА рдмрджрд▓рд╛рд╡ рдЖрдпрд╛ рд╣реИред
- рдЕрдм рдЖрдк рдПрдХ рд╕рд┐рдВрдЧрд▓ рдХрдорд╛рдВрдб рдХреЛ рдкреИрдХреЗрдЬрдмреЙрдбреА рдХреНрд▓рд╛рд╕ рдореЗрдВ рдкрд╛рд╕ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдЬреНрдпрд╛рджрд╛рддрд░ рдорд╛рдорд▓реЛрдВ рдореЗрдВ рдпрд╣ рдХрдорд╛рдВрдбрд╕реНрд╕реЗрдВрд╕ рдХрдорд╛рдВрдб рдХрд╛ рдПрдХ рдЙрджрд╛рд╣рд░рдг рд╣реЛрдЧрд╛ред
- TransactionContainer рдХрдорд╛рдВрдб рд╕реЗ рд╡рд┐рд░рд╛рд╕рдд рдореЗрдВ рдорд┐рд▓реА рдХреНрд▓рд╛рд╕ рдХрд╛ рдЗрд╕реНрддреЗрдорд╛рд▓ рдХрдорд╛рдВрдб рдХреЗ рдЕрдиреБрдХреНрд░рдо рдХреЛ рдЯреНрд░рд╛рдВрдЬреЗрдХреНрд╢рди рдореЗрдВ рд╕рдВрдпреЛрдЬрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдпрд╣ CommandSequence рдХреЗ рд╕рдорд╛рди рд╣реИ, рд▓реЗрдХрд┐рди рдЗрд╕рдореЗрдВ рдПрдХ рдЕрддрд┐рд░рд┐рдХреНрдд TransactionName рдкреИрд░рд╛рдореАрдЯрд░ рд╣реИред
TransactionContainer рдХреЗ рдЕрдВрджрд░, рдореИрдВрдиреЗ рдХрдИ рдлрд╝рд╛рдЗрд▓ рдирд┐рд░реНрдорд╛рдг рдХрдорд╛рдВрдбреНрд╕ рдХреЛ рдиреЗрд╕реНрдЯ рдХрд┐рдпрд╛, рдФрд░ рдЙрдирдХреЗ рдмреАрдЪ рдПрдХ рдЕрдкрд╡рд╛рдж рдлреЗрдВрдХ рджрд┐рдпрд╛ред рдЗрд╕ рдкреИрдХреЗрдЬ рдХрд╛ рд╡реНрдпрд╡рд╣рд╛рд░ рдирд┐рдореНрдирд╛рдиреБрд╕рд╛рд░ рд╣реЛрдЧрд╛:
- рдкреИрдХреЗрдЬ CreateFile рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЛ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдкрд╣рд▓реЗ рджреЛ рдХрдорд╛рдВрдб рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░реЗрдЧрд╛ред
- рддреАрд╕рд░реЗ ThrowException рдХрдорд╛рдВрдб рдкрд░, рдПрдХ рдЕрдкрд╡рд╛рдж рдлреЗрдВрдХ рджрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ рдФрд░ рдкреИрдХреЗрдЬ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рдирд╛ рдмрдВрдж рдХрд░ рджреЗрдЧрд╛, рдЬрд┐рд╕рдХрд╛ рдЕрд░реНрде рд╣реИ рдХрд┐ рдЕрдВрддрд┐рдо CreateFile рдХрдорд╛рдВрдб рдмрд┐рд▓реНрдХреБрд▓ рднреА рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдирд╣реАрдВ рдХрд░реЗрдЧрд╛
- рдпрд╣ рдкреИрдХреЗрдЬ myTransaction рдирд╛рдордХ рд▓реЗрдирджреЗрди рд░реЛрд▓рдмреИрдХ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЗ рд▓рд┐рдП рдЖрдЧреЗ рдмрдврд╝реЗрдЧрд╛, рдЗрд╕рдореЗрдВ рд╢рд╛рдорд┐рд▓ рджреЛ CreateFile рдХрдорд╛рдВрдб рдХреЛ рд╡рд╛рдкрд╕ рд░реЛрд▓ рдХрд░рдХреЗред
рдЗрд╕ рдкреНрд░рдХрд╛рд░, рдПрдХ рд▓реЗрди-рджреЗрди рд░реЛрд▓рдмреИрдХ рд▓реЗрди-рджреЗрди рдореЗрдВ рд╢рд╛рдорд┐рд▓ рд╕рднреА рдкреИрдХреЗрдЬ рдЖрджреЗрд╢реЛрдВ рдХрд╛ рд░реЛрд▓рдмреИрдХ рдирд╣реАрдВ рд╣реИ, рд▓реЗрдХрд┐рди рдХреЗрд╡рд▓ рдкреВрд░реНрдг рд▓реЗрдирджреЗрди рдЖрджреЗрд╢реЛрдВ рдХрд╛ рд░реЛрд▓рдмреИрдХ рд╣реИред
рд╣рдо рдпрд╣ рднреА рдиреЛрдЯ рдХрд░рддреЗ рд╣реИрдВ рдХрд┐ рдкреИрдХреЗрдЬред рдПрдХреНрд╕рдХреНрдпреВрдЯ () рд╡рд┐рдзрд┐ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЛ рдкреИрдХреЗрдЬ рдХреЗ рдирд┐рд╖реНрдкрд╛рджрди рдХреЗ рд╕рдВрджрд░реНрдн рдореЗрдВ, рд╕реВрдЪрдирд╛ рдХреЗ рдкреНрд░рдпреЛрдЬрдиреЛрдВ рдХреЗ рд▓рд┐рдП, рдХрд╣рдиреЗ рджреЗрдВ, рддрд╛рдХрд┐ рдЖрдк рдпрд╣ рджреЗрдЦ рд╕рдХреЗрдВ рдХрд┐ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрдорд╛рдВрдб рдХреЗ рдХреНрдпрд╛ рдкрд░рд┐рдгрд╛рдо рд╣реИрдВ, рд▓реЗрдирджреЗрди рдФрд░ рдкрде рдХреА рд╕реВрдЪреАред
рдкреИрдХреЗрдЬ рдХреНрд▓рд╛рд╕ рдХреА рдПрдХреНрд╕рдХреНрдпреВрдЯ () рдкрджреНрдзрддрд┐ рдПрдХ рдмрд╣реБрдд рд╣реА рдорд╛рдореВрд▓реА рдХрд╛рдо рд╣реИ:
- рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкреИрдХреЗрдЬ рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рд╕рднреА рдлрд╝реЛрд▓реНрдбрд░ рд╕рдВрд░рдЪрдирд╛ рдбрд┐рд╕реНрдХ рдкрд░ рдмрдирд╛рддрд╛ рд╣реИ (рдкреИрдХреЗрдЬ рдХреА рдлрд╝рд╛рдЗрд▓ рдЯреНрд░реА рд╕рдВрд░рдЪрдирд╛ рджреЗрдЦреЗрдВ)
- рдкреИрдХреЗрдЬрдмреЙрдбреА рдХреНрд▓рд╛рд╕ рдХреЗ рдХрдорд╛рдВрдб рдХреА рдбреВ () рд╡рд┐рдзрд┐ рдХреЛ рдХреЙрд▓ рдХрд░рддрд╛ рд╣реИред
рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдЯреАрдореЗрдВ рдЦреБрдж рд╣реА рдЕрдкрдирд╛ рдЕрдорд▓ рд╢реБрд░реВ рдХрд░ рджреЗрддреА рд╣реИрдВред рдпрджрд┐ рдпрд╣ рдПрдХ рдПрдХрд▓ рдХрдорд╛рдВрдб рд╣реИ, рддреЛ рдЗрд╕реЗ рдмрд╕ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдпрджрд┐ рдпрд╣ рдХрдорд╛рдВрдбрд╕реЗрдВрд╕реЗрдВрд╕ рд╣реИ, рддреЛ рдпрд╣ рдХреНрд░рдорд┐рдХ рд░реВрдк рд╕реЗ рдЗрд╕рдореЗрдВ рдирд┐рд╣рд┐рдд рд╕рднреА рдХрдорд╛рдВрдб рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рддрд╛ рд╣реИред рдпрджрд┐ рдпрд╣ рдПрдХ TransactionContainer рд╣реИ, рддреЛ рдпрд╣ рдкрд╣рд▓реЗ рдПрдХ рдирдпрд╛ рд▓реЗрдирджреЗрди рдмрдирд╛рддрд╛ рд╣реИ, рдФрд░ рдлрд┐рд░ рдХреНрд░рдорд┐рдХ рд░реВрдк рд╕реЗ рдЗрд╕рдореЗрдВ рд╕рдВрд▓рдЧреНрди рдЖрджреЗрд╢реЛрдВ рдХреЛ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рддрд╛ рд╣реИ, рдпрд╣ рдЙрдирдХреЗ рд▓рд┐рдП рдПрдХ рддрд░реНрдХ рдХреЗ рд░реВрдк рдореЗрдВ рдирд┐рд░реНрдорд┐рдд рд▓реЗрдирджреЗрди рдХреЛ рдкрд╛рд░рд┐рдд рдХрд░рддрд╛ рд╣реИред рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ, рдЗрд╕ рддрдереНрдп рдХреЛ рдзреНрдпрд╛рди рдореЗрдВ рд░рдЦрдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реИ рдХрд┐ рд▓реЗрди-рджреЗрди рдирд┐рд╖реНрдкрд╛рджрди рдореЗрдВ рд╕рд╣рд╛рдпрддрд╛ рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рд╕рд╛рдзрд╛рд░рдг рдЖрджреЗрд╢ рдФрд░ рдЖрджреЗрд╢ рджреЛрдиреЛрдВ рдХреЛ рд▓реЗрдирджреЗрди рдореЗрдВ рдПрдореНрдмреЗрдб рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рддрджрдиреБрд╕рд╛рд░, TransactionContainer рдХреЛ рдЕрдЧрд▓реЗ рдирд┐рд╖реНрдкрд╛рджрди рдпреЛрдЧреНрдп рдХрдорд╛рдВрдб рдХреЗ рдореВрд▓ рдкреНрд░рдХрд╛рд░ рдХреА рдирд┐рдЧрд░рд╛рдиреА рдХрд░рдиреА рдЪрд╛рд╣рд┐рдП, рдЬреЛ рдЙрди рдкрд░ рд╕рдВрдмрдВрдзрд┐рдд рдЕрдзрд┐рднрд╛рд░ рдбреВ () рд╡рд┐рдзрд┐ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рддрд╛ рд╣реИред TransactionContainer рдЕрдВрддрддрдГ рдкрдХрдбрд╝рдиреЗ рд╡рд╛рд▓реЗ рдХрдВрдЯреЗрдирд░ рдореЗрдВ рдЖрджреЗрд╢реЛрдВ рдХреЗ рдЕрдиреБрдХреНрд░рдо рдХреЛ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рддрд╛ рд╣реИ, рдФрд░ рдпрджрд┐ рдХрд┐рд╕реА рднреА рдиреЗрд╕реНрдЯреЗрдб рдХрдорд╛рдВрдб рдореЗрдВ рдХреЛрдИ рдЕрдкрд╡рд╛рдж рд╣реЛрддрд╛ рд╣реИ, рддреЛ рдЙрд╕реЗ рд╡рд░реНрддрдорд╛рди рд▓реЗрдирджреЗрди рдХреЗ рд░реЛрд▓рдмреИрдХ () рд╡рд┐рдзрд┐ рдХреЛ рдХреЙрд▓ рдХрд░рдХреЗ рд▓реЗрди-рджреЗрди рдХреЛ рд╡рд╛рдкрд╕ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрдЧреЗ рдмрдврд╝рдирд╛ рдЪрд╛рд╣рд┐рдПред рдХрдорд╛рдВрдб рдмреНрд▓реЙрдХ рдХреЗ рдирд┐рд╖реНрдкрд╛рджрди рдХреЗ рдЕрдВрдд рдореЗрдВ, рдпрд╣ рд▓реЗрди-рджреЗрди рдХреЛ рд╕рдВрднрд╡ рдмрд╛рдж рдореЗрдВ рд▓реЛрдб рдХрд░рдиреЗ рдФрд░ рд▓реЗрди-рджреЗрди рдХреЗ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХреЗ рд▓рд┐рдП рдбрд┐рд╕реНрдХ рдкрд░ рд╕рд╣реЗрдЬрддрд╛ рд╣реИред
TransactionContainer рд╡рд░реНрдЧ рдХреА Do () рд╡рд┐рдзрд┐ рдХрд╛ рдХреЛрдб рдкрд╣рд▓реЗ рд╕рдиреНрдирд┐рдХрдЯрди рдХреЗ рд░реВрдк рдореЗрдВ рджрд┐рдЦрддрд╛ рд╣реИ:
Transaction transaction = new Transaction() { TransactionName = TransactionName, TransactionState = TransactionState.Undefined }; try { context.Transactions.Add(transaction); foreach (Command command in Commands) { if (command is TransactionalCommand) { ((TransactionalCommand)command).Do(context, transaction); } else { command.Do(context); } } transaction.TransactionState = TransactionState.Active; } catch { transaction.Rollback(); } finally { transaction.Save(context); }
рдЗрдВрд╕реНрдЯреЙрд▓рд░ рдбрд┐рдЬрд╛рдЗрди рдХреЗ рдЗрд╕ рдЪрд░рдг рдореЗрдВ, TransactionContainer рдЖрджреЗрд╢реЛрдВ рдХреА рдПрдХ рдЖрджреЗрд╢рд┐рдд рд╕реВрдЪреА рд╣реИ рдЬреЛ рдПрдХ рдПрдХрд▓ рд▓реЗрдирджреЗрди рдореЗрдВ рдПрдХ рдХреЗ рдмрд╛рдж рдПрдХ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рд╣реЛрддреА рд╣реИред рд▓реЗрдХрд┐рди рдХреНрдпрд╛ рд╣реЛрдЧрд╛ рдЕрдЧрд░ рдЗрдирдореЗрдВ рд╕реЗ рдПрдХ рдХрдорд╛рдВрдб рдХрдВрдЯреЗрдирд░ рдХрдорд╛рдВрдб рд╣реИ, рдпрд╛рдиреА рдПрдХ рдХрдорд╛рдВрдб рдЬрд┐рд╕рдореЗрдВ рдПрдХ рдпрд╛ рдПрдХ рд╕реЗ рдЕрдзрд┐рдХ рдЕрдиреНрдп рдХрдорд╛рдВрдб рдПрдореНрдмреЗрдбреЗрдб рд╣реИрдВ? рдХреНрдпрд╛ рд╣реЛрдЧрд╛, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдПрдХ ExecuteIf рдпрд╛ CommandSequence рдХрдорд╛рдВрдб рдХреЛ рд▓реЗрдирджреЗрди рдХреЗ рд╣рд┐рд╕реНрд╕реЗ рдХреЗ рд░реВрдк рдореЗрдВ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ? рдЕрдкрдиреЗ рдЖрдк рд╕реЗ, ExecuteIf рдФрд░ CommandSequence рд▓реЗрди-рджреЗрди рдХрд╛ рд╕рдорд░реНрдерди рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВ, рдЬрд┐рд╕рдХрд╛ рдЕрд░реНрде рд╣реИ рдХрд┐ рдпрджрд┐ рд▓реЗрдирджреЗрди рдХрдорд╛рдВрдб рдЙрдирдХреЗ рдЕрдВрджрд░ рдирд┐рд╣рд┐рдд рд╣реИ, рддреЛ рдЗрд╕реЗ рд▓реЗрдирджреЗрди рдХреЗ рджрд╛рдпрд░реЗ рд╕реЗ рдмрд╛рд╣рд░ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛, рдХреНрдпреЛрдВрдХрд┐ ExecuteIf рдФрд░ CommandSequence рдореЗрдВ рдПрдХ рддрд░реНрдХ рдХреЗ рд╕рд╛рде Do (ExecutionContext) рд╡рд┐рдзрд┐рдпрд╛рдБ рд╣реЛрдВрдЧреА, рдХреНрдпреЛрдВрдХрд┐ рд╡реЗ рдЧреИрд░-рд▓реЗрди-рджреЗрди рд╡рд╛рд▓реЗ рд╣реИрдВред ред рдЗрд╕рдХрд╛ рдорддрд▓рдм рдпрд╣ рд╣реИ рдХрд┐ рдЙрдирдореЗрдВ рдПрдореНрдмреЗрдбреЗрдб рдЯреАрдо рд▓реЗрдирджреЗрди рдХреЗ рдмрд╛рд╣рд░ рдХрд╛рдо рдХрд░реЗрдЧреА, рдЬреЛ рдПрдХ рдмрд╣реБрдд рдЕрдЪреНрдЫрд╛ рд╕рдорд╛рдзрд╛рди рдирд╣реАрдВ рд╣реИред
рдЗрд╕рд▓рд┐рдП, рд╕рднреА рдХрдВрдЯреЗрдирд░ рдХрдорд╛рдВрдб (ExecuteIf, ExecuteNotIf рдФрд░ CommandSequence, рдФрд░ рдХреЛрдИ рднреА рдЕрдиреНрдп рдХрдВрдЯреЗрдирд░ рдЬреЛ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдЗрдВрд╕реНрдЯреЙрд▓рд░ рдореЗрдВ рдЬреЛрдбрд╝рддрд╛ рд╣реИ) рдХреЛ рдЯреНрд░рд╛рдВрд╕реЗрдХреНрд╢рдирд▓ рдмрдирд╛рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред рд╣рд╛рд▓рд╛рдВрдХрд┐, рдХрдВрдЯреЗрдирд░ рдХрдорд╛рдВрдб рд╕реНрд╡рдпрдВ рд▓реЗрди-рджреЗрди рдореЗрдВ рдПрдХ рдХрджрдо рдирд╣реАрдВ рдЬреЛрдбрд╝реЗрдЧреА, рдХреНрдпреЛрдВрдХрд┐ рдЗрд╕рдореЗрдВ рдореВрд▓ рд▓реЗрдирджреЗрди рдХреЛ рдмрддрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдХреБрдЫ рднреА рдирд╣реАрдВ рд╣реИ - рдХрдВрдЯреЗрдирд░ рдХрдорд╛рдВрдб рдЦреБрдж рд╕рд┐рд╕реНрдЯрдо рдореЗрдВ рдХреБрдЫ рднреА рдирд╣реАрдВ рдмрджрд▓рддрд╛ рд╣реИред рд╡рд╣ рдЕрдкрдиреА рдиреЗрд╕реНрдЯреЗрдб рдЯреНрд░рд╛рдВрдЬреЗрдХреНрд╢рдирд▓ рдЯреАрдореЛрдВ рдХреЛ рдЪрд░рдгреЛрдВ рдХреЗ рдирд┐рд░реНрдорд╛рдг рдХреЛ рд╕реМрдВрдк рджреЗрдЧреАред рдпрд╣реА рд╣реИ, рдЕрдм рдХреЛрдИ рднреА рдХрдВрдЯреЗрдирд░ рдХрдорд╛рдВрдб рдЗрд╕ рддрд░рд╣ рд╣реЛрдЧрд╛:
- рдЦрд╛рд▓реА рд░реЛрд▓рдмреИрдХ рд╡рд┐рдзрд┐ (TransactionStep)
- Do (ExecutionContext) рд╡рд┐рдзрд┐ рдкрд╣рд▓реЗ рдХреА рддрд░рд╣ рд╣реА рдмрдиреА рд╣реБрдИ рд╣реИ, рдЕрд░реНрдерд╛рдд рдпрд╣ рдХреЗрд╡рд▓ рдПрдХ рдиреЗрд╕реНрдЯреЗрдб рдХрдорд╛рдВрдб рдпрд╛ рдХрдорд╛рдВрдб рдХреЛ рдХрдВрдЯреЗрдирд░ рдХрдорд╛рдВрдб рдХреЗ рдЖрдВрддрд░рд┐рдХ рддрд░реНрдХ рдХреЗ рдЕрдиреБрд╕рд╛рд░ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рддрд╛ рд╣реИ, Do (ExecutionContext) рд╡рд┐рдзрд┐ рдХреЛ рдЗрд╕рдХреЗ рдпрд╛ рдЙрдирдХреЗ рдПрдХ рддрд░реНрдХ рдХреЗ рдЕрдиреБрд╕рд╛рд░ рд▓рд╛рдЧреВ рдХрд░рддрд╛ рд╣реИред
- рджреЛ рддрд░реНрдХреЛрдВ рдХреЗ рд╕рд╛рде Do (ExecutionContext, Transaction) рд╡рд┐рдзрд┐ Do (ExecutionContext) рд╡рд┐рдзрд┐ рдХреЗ рдЖрдВрддрд░рд┐рдХ рддрд░реНрдХ рдХреЛ рджреЛрд╣рд░рд╛рддреА рд╣реИ, рд▓реЗрдХрд┐рди рдПрдХ рд╣реА рд╕рдордп рдореЗрдВ рдпрд╣ рдЬрд╛рдВрдЪ рдХрд░рддреА рд╣реИ рдХрд┐ рдХрд┐рд╕ рд╕реЗ рдиреЗрд╕реНрдЯреЗрдб рдХрдорд╛рдВрдб рдпрд╛ рдХрдорд╛рдВрдб рд╡рд┐рд░рд╛рд╕рдд рдореЗрдВ рдорд┐рд▓реА рд╣реИрдВ, рдФрд░ рдпрджрд┐ рдЙрд╕реЗ TransactionalCommand рд╕реЗ рд╡рд┐рд░рд╛рд╕рдд рдореЗрдВ рдорд┐рд▓рд╛ рд╣реИ, рддреЛ рд╡рд╣ рдЕрдкрдиреЗ Do (ExecutionContext) рд▓реЗрдирджреЗрди рдХреЛ рдХреЙрд▓ рдХрд░рддрд╛ рд╣реИред рдЕрдиреНрдпрдерд╛, Do (ExecutionContext) рд╡рд┐рдзрд┐ред рдпрд╣реА рд╣реИ, рдиреЗрд╕реНрдЯреЗрдб рдХрдорд╛рдВрдб рдХреЗ рд▓реЗрди-рджреЗрди рдХрд╛ рд╕рддреНрдпрд╛рдкрди TransactionContainer рд╡рд░реНрдЧ рд╕реЗ рдХрдВрдЯреЗрдирд░ рдХреНрд▓рд╛рд╕ рдореЗрдВ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рд╣реЛ рдЧрдпрд╛ рд╣реИред
- рдЪреВрдВрдХрд┐ рдХрдВрдЯреЗрдирд░ рдХрдорд╛рдВрдб рдкреИрд░реЗрдВрдЯ рдЯреНрд░рд╛рдВрдЬреИрдХреНрд╢рди рдореЗрдВ рдЕрдкрдирд╛ рдХрджрдо рдирд╣реАрдВ рдмрдирд╛рддрд╛ рд╣реИ, Do (ExecutionContext, Transaction) рд╡рд┐рдзрд┐ рд░рд┐рдЯрд░реНрди рджреЗрддреА рд╣реИред
рдЬреИрд╕рд╛ рдХрд┐ рдКрдкрд░ рдмрддрд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ, CommandSecquence рдФрд░ ExecuteIf рдХрдХреНрд╖рд╛рдПрдВ рдЕрдм рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрддреА рд╣реИрдВ:
public class CommandSequence: TransactionalCommand { public List<Command> Commands; public override void Do(ExecutionContext context) { foreach (Command command in Commands) { command.Do(context); } } public override TransactionStep Do(ExecutionContext context, Transaction transaction) { foreach (Command command in Commands) { if (command is TransactionalCommand) { ((TransactionalCommand)command).Do(context, transaction); } else { command.Do(context); } } return null; } public override void Rollback(TransactionStep step) { } } public class ExecuteIf : TransactionalCommand { public string ArgumentName { get; set; } public Command Command { get; set; } public override void Do(ExecutionContext context) { if ((bool)context.GetResult(ArgumentName)) { Command.Do(context); } } public override TransactionStep Do(ExecutionContext context, Transactions.Transaction transaction) { if ((bool)context.GetResult(ArgumentName)) { if (Command is TransactionalCommand) { ((TransactionalCommand)Command).Do(context, transaction); } else { Command.Do(context); } } return null; } public override void Rollback(TransactionStep step) { } }
рдЕрдм рд╣рдо рдХрд┐рд╕реА рднреА рд╕реНрддрд░ рдХреЗ рдШреЛрдВрд╕рд▓реЗ рдХреЗ рдХрдорд╛рдВрдб рд╡рд╛рд▓реЗ рд▓реЗрдирджреЗрди рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВред
рддреАрд╕рд░реЗ рднрд╛рдЧ рдХрд╛ рд▓рд┐рдВрдХ